home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / basic / qbnws201.zip / QBNWS201.NWS < prev    next >
Text File  |  1991-02-28  |  129KB  |  2,826 lines

  1.      Volume  2, Number  1                                 February 28, 1991
  2.  
  3.      
  4.      
  5.      
  6.      
  7.      
  8.      
  9.      
  10.      
  11.      
  12.      
  13.      
  14.      
  15.                    **************************************************
  16.                    *                                                *
  17.                    *                    QBNews                      *
  18.                    *                                                *
  19.                    *      International QuickBASIC Electronic       *
  20.                    *                  Newsleter                     *
  21.                    *                                                *
  22.                    *    Dedicated to promoting QuickBASIC around    *
  23.                    *                  the world                     *
  24.                    *                                                *
  25.                    **************************************************
  26.      
  27.      
  28.      
  29.      
  30.      
  31.      
  32.      
  33.      
  34.      
  35.      
  36.      
  37.      
  38.      
  39.      
  40.      
  41.      
  42.         The  QBNews  is  an electronic newsletter  published  by  Clearware
  43.      Computing. It can be freely distributed providing NO CHARGE is charged
  44.      for  distribution.  The  QBNews is copyrighted in  full  by  Clearware
  45.      Computing.  The  authors  hold  the  copyright  to  their   individual
  46.      articles.  All program code appearing in QBNews is released  into  the
  47.      public  domain.   You  may  do what you  wish  with  the  code  except
  48.      copyright  it.  QBNews  must  be  distributed  whole  and  unmodified.
  49.      
  50.      You can write The QBNews at:
  51.      
  52.           The QBNews
  53.           P.O. Box 507
  54.           Sandy Hook, CT 06482
  55.      
  56.      Copyright (c) 1991 by Clearware Computing.
  57.      
  58.      The QBNews                                                   Page    i
  59.      Volume  2, Number  1                                 February 28, 1991
  60.  
  61.      
  62.  
  63.      ----------------------------------------------------------------------
  64.  
  65.                         T A B L E   O F   C O N T E N T S
  66.  
  67.      
  68.      1.  From the Editor's Desk
  69.           Happy Birthday To Us .........................................  1
  70.  
  71.      2.  Beginners Corner
  72.           How I Came To Know And Love ANSI.SYS by Charles Graham .......  2
  73.           Intellectual Property Protection by David Postler ............  9
  74.  
  75.      3.  Swap Shop
  76.           Getting and Setting Bits by Richard Randles .................. 17
  77.           Reversing Color Attributes by Rick Cooper .................... 18
  78.           Detecting DesqView from QB by Monte Ferguson ................. 19
  79.           Getting and Setting File Attributes by Rick Cooper ........... 20
  80.           Everything You Want To Know About A Program by Keith Rolland . 22
  81.           Playing Around With Random Numbers by James Young ............ 24
  82.  
  83.      4.  Grapically Speaking
  84.           Reading Print Shop Graphics in QuickBASIC by Michael Welch ... 25
  85.  
  86.      5.  Power Programming
  87.           Creating Smaller QB Executables  by T. G. Muench ............. 28
  88.  
  89.      6.  New and Noteworthy
  90.           PDQComm 2.5 from Crescent Software ........................... 33
  91.  
  92.      7.  Some Assembly Required
  93.           Setting Error Levels with QuickBASIC by Dave Cleary .......... 34
  94.  
  95.      8.  Psst ... Looking For A Library?
  96.           An Introduction to QuickSHARE by Michael Welch ............... 37
  97.  
  98.      9.  EOF
  99.           Receiving The QBNews ......................................... 40
  100.           Submitting Articles to The QBNews ............................ 41
  101.           Volume One Cumulative Index .................................. 42
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.      The QBNews                                                   Page    ii
  118.      Volume  2, Number  1                                 February 28, 1991
  119.  
  120.  
  121.  
  122.      ----------------------------------------------------------------------
  123.                    F r o m   t h e   E d i t o r ' s   D e s k
  124.      ----------------------------------------------------------------------
  125.  
  126.      The QBNews Turns Two ! ! !
  127.      
  128.         Welcome to the first installment of Volume 2 of The QBNews. As the
  129.      QBNews goes into its second year, I would like to thank everybody who has
  130.      contributed to make Volume 1 as good as it was.
  131.      
  132.         Now comes the bad news. As good as the QBNews has been, I've been
  133.      working to make it better. I have wanted to be able to offer authors some
  134.      cash for their work. This would result in much better articles. I
  135.      wanted to do this by selling advertising to companies who sell
  136.      QuickBASIC related products. Unfortunately, because the QBNews is a
  137.      different kind of magazine in as far as distribution goes, I have no
  138.      way to gauge readership. I know and you know that the QBNews has many
  139.      readers all over the world. The companies I approached about
  140.      advertising don't know and don't consider The QBNews seriously when it
  141.      comes to spending advertising dollars.
  142.      
  143.         I urge all of you out there to help out. If you see a product or company
  144.      mentioned in the QBNews and you purchase it, let them know where you heard
  145.      about it. The only alternative if I can't raise money from advertisers is
  146.      to raise money from readers. Come the November issue, I will have to decide
  147.      on the fate of Volume 3.
  148.      
  149.         One final note. There is a bug in QBFormat from the last QBNews. In
  150.      the SUB InitFormatParms under the SELECT CASE media, it should read:
  151.      
  152.         CASE DX9
  153.            Info.Ts = 1440
  154.      
  155.      It previously read 720. Also, QBFormat contains an unimplemented feature
  156.      that will allow booting from hard drive C: with a QBFormated floppy in
  157.      drive A:. Line 103, column 19 is &H50. Changing &H50 to &H80 will turn that
  158.      feature on.
  159.      
  160.         Enjoy your QBNews!
  161.         Dave Cleary - Editor
  162.      
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.      The QBNews                                                     Page  1
  177.      Volume  2, Number  1                                 February 28, 1991
  178.  
  179.  
  180.  
  181.      ----------------------------------------------------------------------
  182.                          B e g i n n e r s   C o r n e r
  183.      ----------------------------------------------------------------------
  184.  
  185.      How I Came To Know And Love ANSI.SYS by Charles Graham
  186.      
  187.         One morning close to a year ago, I woke up and was troubled about
  188.      the future of QuickBASIC.  It's a language I know and love and teach,
  189.      but I kept coming back to a central question.  If QB is so great,
  190.      where are the application programs written in QB?  At the time, I
  191.      didn't know of any.  (I have since learned that there *are* a few such
  192.      critters.  But I didn't know that then.) So I decided I would try to
  193.      write such a program.  I considered many possibilities.  What I really
  194.      wanted was something that could be distributed nationally, would be of
  195.      general interest, and would be noticed by devotees of C, Pascal and
  196.      Assembly.  The idea wasn't intended to show the superiority of QB, it
  197.      was just to stand on an equal footing. 
  198.      
  199.         Being the fan of Bulletin Boards that I am, I finally decided that
  200.      writing a full-featured communications (or terminal) program would be
  201.      just the ticket.  There was only one small remaining problem:  I
  202.      didn't know anything about communications.  I was at the bottom of a
  203.      very steep learning curve.  But that morning I set out to write -- and
  204.      eventually *did* write -- Quick Dial.
  205.      
  206.         Talk about Trial And Error!  One of the first things I discovered
  207.      is that there are few -- if any -- useful written resources for
  208.      writing *modern* communications software.  What do you do about the
  209.      animation and color that's the staple of modern BBSs?  Nobody says
  210.      much about that.  Oh sure.  There's the example in the back of the
  211.      GWBASIC manual you get with DOS.  There's TERMINAL.BAS that comes with
  212.      QB.  There's the fine print in the Appendices at the back of your
  213.      modem manual.  And I *did* locate a text file on file transfer
  214.      protocols.  But put it all together and it's still not worth six bits.
  215.      It's pretty skimpy and pretty lame. 
  216.      
  217.         For the purpose of writing Quick Dial, I decided that I would have
  218.      to write my own ANSI emulation subprograms.  And after a lot of pain
  219.      and heartache, I eventually did.  But that's not where I started a
  220.      year ago.  I started by utilizing plain, old, vanilla-flavored,
  221.      everybody's-friend, comes-for-free- with-DOS, ANSI.SYS. Using ANSI.SYS
  222.      is what Z.BAS is all about.
  223.      
  224.      WHY USE ANSI.SYS?
  225.      
  226.         There are three very good reasons.
  227.      
  228.           * ANSI.SYS is a relatively efficient way to handle screen writes.
  229.        
  230.           * Using ANSI.SYS is a *lot* easier than writing ANSI emulation
  231.             routines.
  232.          
  233.           * Even if you're tempted to write your own ANSI emulation
  234.             routines,using ANSI.SYS is a good way to get familiar with what
  235.      
  236.      The QBNews                                                     Page  2
  237.      Volume  2, Number  1                                 February 28, 1991
  238.  
  239.             ANSI does and how it does it, before you start writing your own
  240.             routines.
  241.      
  242.      
  243.      
  244.      ARE THERE ANY DISADVANTAGES TO USING ANSI.SYS?
  245.      
  246.         There are only two that I know of.
  247.      
  248.           * The statements required to use ANSI.SYS are slightly longer and
  249.             more complex than the equivalent statements would be without
  250.             using ANSI.SYS.
  251.          
  252.           * You will, effectively, not be able to keep a "command line"
  253.             visible on the screen at all times.  This is a popular, but
  254.             unnecessary, convention in many commercial communications
  255.             packages.
  256.      
  257.      
  258.      
  259.      WHAT IS ANSI.SYS?
  260.      
  261.         ANSI.SYS is many things.  But for purposes of communications
  262.      software, you can think of ANSI.SYS as a standardized set of
  263.      instructions that does four things
  264.      
  265.           * clears all or part of the screen
  266.           * locates the cursor
  267.           * changes the foreground and background colors
  268.           * performs all screen writes
  269.      
  270.         ANSI.SYS performs its wonders by interpreting special sequences of
  271.      characters that it receives through the modem from a Bulletin Board.
  272.      These sequences are referred to as ANSI sequences or ESCape sequences. 
  273.      
  274.         Each ANSI sequence begins with an ESCape character which I will
  275.      refer to as <ESC>.  <ESC> is ASCII character 27 which QD knows as
  276.      CHR$(27).  <ESC> is always followed by a left bracket.  Then none, one
  277.      or multiple sequences of digits may be received.  If multiple
  278.      sequences of digits are received, they are separated by semi-colons.
  279.      Finally, each ANSI sequence terminates with an UPPER or lower case
  280.      letter that indicates which ANSI command you need to perform.  
  281.      
  282.      
  283.      WHAT ARE THE ANSI.SYS COMMANDS?
  284.      
  285.         For communications purposes, there are 13 ANSI commands indicated
  286.      by the terminal letters
  287.      
  288.         H A B C D R n f s u J K m
  289.         [Note. CaSe Is ImPoRtAnT.  "A" does not equal "a".]
  290.      
  291.      Here's the syntax and what each of these commands means.
  292.      
  293.      
  294.      The QBNews                                                     Page  3
  295.      Volume  2, Number  1                                 February 28, 1991
  296.  
  297.      <ESC>[row;colH -- The Cursor Position command moves the cursor to the 
  298.      position specified by the parameters row and col.  The default for
  299.      each parameter is 1.  No parameters homes the cursor. 
  300.      
  301.      <ESC>[#A -- The Cursor Up command moves the cursor up the number of
  302.      lines specified by the parameter #.  The default value is 1.  Cursor
  303.      Up is ignored if the cursor is already on the top row. 
  304.      
  305.      <ESC>[#B -- The Cursor Down command moves the cursor down the number
  306.      of lines specified by the parameter #.  The default value is 1.
  307.      Cursor Down is ignored if the cursor is already on the bottom row. 
  308.      
  309.      <ESC>[#C -- The Cursor Right command moves the cursor right the number
  310.      of columns specified by the parameter #.  The default value is 1.
  311.      Cursor Right is ignored if the cursor is already in the far right
  312.      column. 
  313.      
  314.      <ESC>[#D -- The Cursor Left command moves the cursor left the number
  315.      of columns specified by the parameter #.  The default value is 1.
  316.      Cursor Left is ignored if the cursor is already if the far left
  317.      column. 
  318.      
  319.      <ESC>[row;colR -- A Cursor Position Report is generated by the Device 
  320.      Status Report command, below.  The parameter row contains the cursor's 
  321.      current line number; col contains the cursor's current column. 
  322.      
  323.      <ESC>[6n -- The Device Status Report command triggers a Cursor
  324.      Position Report, above, being generated. 
  325.      
  326.      <ESC>[row;colf -- The Horizontal and Vertical Position command works 
  327.      exactly like the Cursor Position command, above. 
  328.      
  329.      <ESC>[s -- The Save Cursor Position command stores the cursor's
  330.      current row and column.  This is used in conjunction with the Restore
  331.      Cursor Position command, below.
  332.      
  333.      <ESC>[u -- The Restore Cursor Position command restores the cursor's 
  334.      position to the location stored by the Save Cursor Position command,
  335.      above.
  336.      
  337.      <ESC>[2J -- The Erase Display command clears the screen and homes the 
  338.      cursor.
  339.      
  340.      <ESC>[K -- The Erase Line command clears from the current cursor
  341.      position to the end of the line.  
  342.      
  343.      
  344.      <ESC>[#;...;#m -- The Set Graphics Rendition command changes screen
  345.      colors according to any valid # parameters.  The following schedule
  346.      lists allowable values for the # parameters and the meaning of each. 
  347.      
  348.         0 all attributes off
  349.         1 bold (or bright) on
  350.         4 underscore on (monochrome screens only)
  351.      
  352.      The QBNews                                                     Page  4
  353.      Volume  2, Number  1                                 February 28, 1991
  354.  
  355.         5 blink on
  356.         7 reverse video on
  357.         8 concealed on
  358.      
  359.         30 black   foreground
  360.         31 red     foreground
  361.         32 green   foreground
  362.         33 yellow  foreground
  363.         34 blue    foreground
  364.         35 magenta foreground
  365.         36 cyan    foreground
  366.         37 white   foreground
  367.      
  368.         40 black   background
  369.         41 red     background
  370.         42 green   background
  371.         43 yellow  background
  372.         44 blue    background
  373.         45 magenta background
  374.         46 cyan    background
  375.         47 white   background
  376.      
  377.      
  378.      
  379.      INSTALLING ANSI.SYS
  380.      
  381.         You need to make sure that the ANSI.SYS driver appears in your
  382.      CONFIG.SYS file and that your system knows where to find the file,
  383.      ANSI.SYS. There should be a statement in your CONFIG.SYS file that
  384.      says something like
  385.      
  386.         DEVICE=[d:][path]ANSI.SYS
  387.      
  388.      where "d:" is an optional drive name and "path" is an optional
  389.      directory name (and subdirectory name, if applicable) where the file,
  390.      ANSI.SYS is located.  For example, if ANSI.SYS was on the C: drive in
  391.      a directory called DOS, the line in your CONFIG.SYS file should read
  392.      
  393.         DEVICE=C:\DOS\ANSI.SYS
  394.      
  395.      [Note.  Some systems only require a space instead of an equals ("=")
  396.      sign.  Consult your DOS manual.] 
  397.      
  398.         That's all there is to it.  By the way, if you are just entering
  399.      this line in CONFIG.SYS for the first time, you will have to reboot
  400.      your system before ANSI.SYS is actually installed.  Thereafter,
  401.      ANSI.SYS will be installed automatically each time you boot up. 
  402.      
  403.      
  404.      ACCESSING ANSI.SYS IN A COMMUNICATIONS (TERMINAL) PROGRAM
  405.      
  406.         You need to open the "console" as a file.  Opening the "console"
  407.      gives you access to the ANSI.SYS device driver that you've installed
  408.      in your CONFIG.SYS file.  Opening the "console" is easy to do in
  409.      
  410.      The QBNews                                                     Page  5
  411.      Volume  2, Number  1                                 February 28, 1991
  412.  
  413.      QuickBASIC.  Just enter a statement like
  414.      
  415.         OPEN "CON" FOR OUTPUT AS filenum
  416.      
  417.      where filenum is the file number you want to write to.  For example,
  418.      if you want to open the "console" as file number 2, you'd enter
  419.      
  420.         OPEN "CON" FOR OUTPUT AS 2
  421.      
  422.         Thereafter, everything you write to file number 2 will be handled
  423.      by ANSI.SYS and *not* QuickBASIC.
  424.      
  425.      
  426.      
  427.      USING ANSI.SYS IN A COMMUNICATIONS (TERMINAL) PROGRAM
  428.      
  429.         An important hint about using ANSI.SYS is to use it exclusively, or
  430.      don't use it at all.  I.E., ANSI.SYS and QuickBASIC don't talk to each
  431.      other very much -- one doesn't know what the other's doing.  If you
  432.      want to use ANSI.SYS to take care of your screen functions then you
  433.      should *not* use statements like: 
  434.      
  435.         LOCATE
  436.         PRINT
  437.         CLS
  438.         COLOR
  439.      
  440.         Instead, use the equivalent ANSI commands and send them through
  441.      ANSI.SYS by entering 
  442.      
  443.         PRINT #filenum, ANSIcommand;
  444.      
  445.      where "filenum" is the file number that you opened the "console" under
  446.      and "ANSIcommand" is the specific ANSI command you want to perform
  447.      including any necessary parameters. 
  448.      
  449.         Another hint is to store some of the common ANSI characters and
  450.      commands in SHARED string variables.  This makes programming a little
  451.      easier and execution speed a little faster.  In Z.BAS, I did this in
  452.      four cases. 
  453.      
  454.      DIM SHARED ao$, cs$, es$, hc$
  455.      es$ = CHR$(27)                 'this is the <ESC> character
  456.      ao$ = es$ + "[0m"              'this turns all screen attributes off
  457.      cs$ = es$ + "[2J"              'this clears the screen and homes the
  458.      cursor hc$ = es$ + "[f"        'this homes the cursor
  459.      
  460.      "SHARED" means you can use these shortcuts in all subprograms without 
  461.      having to define them in each one.  
  462.      
  463.      
  464.      SOME PROGRAMMING EXAMPLES
  465.      
  466.         For these examples, let's assume you have opened the "console" as
  467.      
  468.      The QBNews                                                     Page  6
  469.      Volume  2, Number  1                                 February 28, 1991
  470.  
  471.      file number 2. 
  472.      
  473.         Suppose you want to change the screen colors to bright cyan on a
  474.      black background before printing some text.  You *could* use the
  475.      QuickBASIC statement 
  476.      
  477.         COLOR 11, 0
  478.      
  479.      But don't!  Do it the ANSI.SYS way.  The statement you need is
  480.      
  481.         PRINT #2, es$ + "[0;1;36;40m";
  482.      
  483.      where
  484.         0 turns all attributes off
  485.         1 turns the "bold" or "bright" attribute on
  486.         36 specifies a cyan foreground
  487.         40 specifies a black background
  488.         m specifies the Set Graphics Rendition command
  489.      
  490.         Suppose you want to clear the screen and home the cursor.  You
  491.      *could* use the QuickBASIC statement
  492.      
  493.         CLS
  494.      
  495.      But don't!  The statement you need is
  496.      
  497.         PRINT #2, cs$;
  498.      
  499.         Or suppose you're editing a field and want to emulate the action of
  500.      a destructive backspace.  You *could* use the QuickBASIC code 
  501.      
  502.         LOCATE , POS(0) - 1
  503.         PRINT " ";
  504.         LOCATE , POS(0) - 1
  505.      
  506.      But don't!  The code you need is
  507.      
  508.         PRINT #2, es$ + "[1D";
  509.         PRINT #2, " ";
  510.         PRINT #2, es$ + "[1D"; 
  511.      
  512.      
  513.      WHAT IF I NEED MORE INFORMATION?
  514.      
  515.         I hope you'll be able to see how to use ANSI.SYS when you review
  516.      the source code for Z.BAS.  Many of the ANSI commands are used.  By
  517.      running, or compiling and running, Z.BAS you'll be able to compare the
  518.      code to the action.  But if questions do arise, I'll be happy to *try*
  519.      to answer them.  
  520.      
  521.         The best place to leave questions for me is in the National
  522.      QuickBASIC Conference.  If you do not belong to a BBS that carries
  523.      same, I would strongly suggest that you ask around to find a local
  524.      Board that *does*.  It's loaded with folks who know *lots* of stuff
  525.      
  526.      The QBNews                                                     Page  7
  527.      Volume  2, Number  1                                 February 28, 1991
  528.  
  529.      about QuickBASIC and who are willing to talk to you! 
  530.      
  531.      **********************************************************************
  532.      Charles Graham is a division head for a local government agency in St.
  533.      Louis County, Missouri. He also teaches QuickBASIC part time at a
  534.      local community college. He is the author of several shareware
  535.      products including MOVIES . ON . LINE and Quick Dial. He can be
  536.      contacted at Post Office  Box 58634, St.  Louis, MO 63158, and on the
  537.      National QuickBASIC Conference.
  538.      **********************************************************************
  539.      
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.      The QBNews                                                     Page  8
  584.      Volume  2, Number  1                                 February 28, 1991
  585.  
  586.      Staking a Claim.  Intellectual Property Protection for Software.
  587.      By David Postler
  588.      
  589.           Well, you have finally done it.  Your program works flawlessly,
  590.      the code is a wonder to behold and is the kind of program that no
  591.      computer owner can be without.  But... How do you protect yourself
  592.      from being ripped off??  This article will give a very basic
  593.      introduction to intellectual property protection.
  594.      
  595.                            *****DISCLAIMERS*****
  596.           First let's get a few things out of the way. I AM NOT A LAWYER!
  597.      Any specific questions should be referred to an attorney skilled in
  598.      copyright/Patent and other intellectual property laws.Second,
  599.      intellectual property law varies from area to area.  This article will
  600.      cover general U.S. law on the subject.  This will vary from country to
  601.      country and even from state to state.  Third, my experience comes from
  602.      many years in engineering jobs and also from my free lance writing
  603.      experience.  I've found that knowing the law makes it harder to rip
  604.      you off.  
  605.      
  606.           Intellectual property law has a history that dates from a law
  607.      called the Statue of Anne in 1710 by the English Parliament.  It was
  608.      the first copyright law granting authors the right to control
  609.      publication of their work.  In addition, kings used to grant Letters
  610.      of Patent to allow inventors or others to profit from their work.
  611.      Intellectual property law was also important to the founding fathers.
  612.      Remember, Jefferson and Franklin among others both  had scientific and
  613.      literary reputations in addition to their political skills.  In the
  614.      constitution of the United States Article 1 section 8 states:
  615.      
  616.           "To promote the Progress of Science and  useful Arts, by 
  617.      securing for limited time to Authors and Inventors the exclusive 
  618.      Right to their respective Writings and Discovery."
  619.      
  620.           Trademark protection came along in the late 1800's.  Trade 
  621.      secret protection relies on contract law and also came along in the
  622.      late 1800's or early 1900's.  For those in the international arena,
  623.      many treaties have been negotiated regarding intellectual property
  624.      laws.  The laws have been updated as the times change. The last major
  625.      revision of the copyright act was in 1978 with minor changes in 1980.
  626.      Patent law has also been updated to reflect the changing times.   It
  627.      should be clear from all this that intellectual property is regarded
  628.      as property and can be protected.  It should also be clear that such
  629.      protection is for a limited time only.  Any person thinking otherwise
  630.      should read some of the books and magazine articles listed at the end
  631.      of this article.
  632.      
  633.           Another major consideration for all intellectual property law is,
  634.      who owns the work.  There are several things to watch out for.  First
  635.      is public domain work.  This is work that either the Copyright/Patent
  636.      has expired or has not been protected.  Older work such as Shakespeare
  637.      is Public domain.  Other works that are not protected include most
  638.      government works and other works that the authors simply do not care
  639.      to protect them.  One thing to remember is that Shareware or Freeware
  640.      
  641.      The QBNews                                                     Page  9
  642.      Volume  2, Number  1                                 February 28, 1991
  643.  
  644.      is NOT THE SAME AS PUBLIC DOMAIN!!!  If you remember anything from
  645.      this article remember that.
  646.      
  647.         The next thing is the problem of work for hire.  This varies
  648.      greatly from state to state, but in general, if you do work for your
  649.      employer within the scope of your employment, then the work belongs to
  650.      your employer.  An example is if you are a database programmer and
  651.      program a database at work, it belongs to your employer.   If you do
  652.      it at home, it may belong to your employer and it may not. This varies
  653.      from state to state.  On the other hand if your job title is
  654.      "Assistant Night Custodial Engineer III", (Janitor), any programming
  655.      that you do outside of work does not belong to your employer.  What if
  656.      you are an outside contractor?  There was a very involved case
  657.      recently (Reid vs Community for Creative Non Violence) that settled
  658.      some of the law as it regards to that area.  To save trouble, you
  659.      should make sure that those matters are settled in the contract. If
  660.      you are a regular employee, it helps to have a policy on this stated
  661.      up front rather than fighting it out in the courts.  For the sake of
  662.      argument, we will assume that your work does not fit in any of these
  663.      categories meaning it is yours and you can legally protect it.
  664.      
  665.           The first protection you will run across is Copyright.  This 
  666.      is quite literally the right to make copies.  It can protect your 
  667.      computer program and possibly the screens or other visual or 
  668.      audio aspects of your program.  In most cases, this is the only 
  669.      protection you will have available for a computer program should be
  670.      all you need.  Copyright protection is automatic. As soon as your work
  671.      is fixed in a tangible form of expression, a copyright exists.  In
  672.      other words, when your program is saved to disk you have a copyright.
  673.      
  674.         So why do you have to register?  First, it proves your authorship
  675.      from the date the software is received by the copyright office.
  676.      Second, you can obtain statutory damages from any person who steals
  677.      your code.  More about that later.  A very common myth is that you
  678.      should seal your work in an envelope and send it to yourself.
  679.      According to the copyright office, this has never held up in court.
  680.      One reason it might not is, how can you prove that the envelope has
  681.      not been altered over the years?  If any other person could prove that
  682.      it is possible that you could have altered the contents of the
  683.      envelope then it could be considered "tainted" and not be allowed as
  684.      evidence in a court.  Registered mail might be better but, best of
  685.      all, register your work.  A copyright certificate is Prima Face
  686.      evidence of your work.  To register, call the Copyright office to get
  687.      the appropriate forms and information.  The numbers are listed at the
  688.      end of this article.
  689.      
  690.         Basically, you must send in a copy of your program source code.  If
  691.      you wish to copyright the screens then you must send descriptions,
  692.      pictures or videotapes to the copyright office in addition to your
  693.      source code.  There are special exemptions to disclosure requirements
  694.      if you wish to keep your program secret.  You may block out or not
  695.      send in certain portions of the program. Contact the copyright office
  696.      and ask for circular R61 for details. 
  697.      
  698.      
  699.      The QBNews                                                     Page 10
  700.      Volume  2, Number  1                                 February 28, 1991
  701.  
  702.           What protection does a copyright give you? The right to make
  703.      copies, with some exceptions. First, any owner of a computer program
  704.      may make an archival copies, but may not distribute them.  Second, the
  705.      owner may alter the program if necessary for use on a particular
  706.      computer.  Bear in mind that  these two items may be constrained by
  707.      the license agreement.  Third is the fair use doctrine.  This is a bit
  708.      nebulous but if the use of a program is for instructional purposes and
  709.      DOES NOT HARM the rights of a copyright holder, it is allowable.  For
  710.      example, say that an English teacher may see your instructions for
  711.      installing your game and consider them a model of clarity (or disaster
  712.      of the first rate) and desire to show portions of the manuals to their
  713.      class as an example.  That probably would be allowable.  On the other
  714.      hand, if a Computer Science department decided to make multiple copies
  715.      of your program instead of buying them, this probably would be
  716.      considered infringement.  There are some other instances where copying
  717.      is permitted, but in mast cases, they are for non commercial use only.
  718.      If they are commercial (for example jukeboxes) they usually include
  719.      mandatory royalties.  The second right given is the right to prepare
  720.      derivative works.  This means that the copyright owner must be
  721.      consulted to prepare new versions of a program. This may even include
  722.      translation to other computer languages.   This means that you may not
  723.      rewrite someone's program, EVEN IF YOU IMPROVE IT, and then claim it
  724.      as your own.   The protection lasts for the life of the author PLUS 50
  725.      years.  If there are joint authors, the term is until 50 years after
  726.      the death of the last surviving author.  For works for hire, the term
  727.      is 100 years after creation or 75 years after publication, whichever
  728.      comes first.  
  729.      
  730.           At first glance, copyright protection would be all you need.  
  731.      So why do we have other types of protection in addition to 
  732.      copyright?  Well, Copyright protection does have some 
  733.      limitations.  First, it protects only the expression of the idea
  734.      not the idea itself.  If someone else comes up with another way 
  735.      to do the same idea, then you have no right to compensation from
  736.      them.  With some precautions, you can legally reverse engineer a 
  737.      copyright. However, talk to an attorney first.  Also, copyright
  738.      must be an original and non obvious way of doing something.  For 
  739.      example, you can't copyright the Print Screen key on an IBM
  740.      keyboard as part of your program.
  741.      
  742.         Another question concerns "look and feel" and the Lotus decision.
  743.      My research (I read the entire opinion) indicates that there really is
  744.      not much to fear.  What the judge said, in essence, is that you cannot
  745.      deliberately copy another programmer's work down to the last keystroke
  746.      and hide behind copyright law.  He specifically rejected look and feel
  747.      on its own as a legitimate test for infringement.  The judge went to
  748.      great pains to point out that there was more than one way that a
  749.      spreadsheet could be programmed and cited Excel as an example.  
  750.      Furthermore, it was admitted by VP software that they changed VP
  751.      Planner to duplicate 1-2-3 down to the last keystroke.  According to
  752.      the judge that was one step too far.
  753.      
  754.         How do you enforce your copyright?  Send Sgt. Joe "We take
  755.      copyright law seriously in this town mister!" Friday over to bust
  756.      
  757.      The QBNews                                                     Page 11
  758.      Volume  2, Number  1                                 February 28, 1991
  759.  
  760.      them.  Sorry folks it doesn't work that way.  In almost all cases
  761.      copyright infringement is considered a civil matter.  This means that
  762.      you must prove that the person actually copied your work.  There are
  763.      two general parts to this.  First, there must be at least one valid
  764.      copyright notice in the work in plain view.  Another idea from the
  765.      book "The Legal Guide to Computer Software Protection" is to include
  766.      some nonsense code in your work.  For example:
  767.      
  768.         AHCTOG$ = "RELTSOP DIVAD YB 1991 THGIRYPOC"
  769.           
  770.      Does not seem like much but by reversing the strings you get:
  771.      
  772.           GOTCHA$ = "COPYRIGHT 1991 BY DAVID POSTLER"
  773.      
  774.         If something like this were found in an offender's code, your next
  775.      step would be to prove how much money the "creep" should pay you.
  776.      Bear in mind that if you registered your code within the first three
  777.      months of publication, you would be entitled to $100/copy Statutory
  778.      damages plus Attorneys fees and court costs.  Whether or not you
  779.      registered your work, you can always get an injunction stopping the
  780.      infringer from using your work and if you can prove that losses
  781.      resulted from infringement, you can recover damages.  Be creative in
  782.      the nonsense code department. Do nothing loops or GOTO statements for
  783.      the next line can also be used.  Another idea used by several people
  784.      on the Fidonet Quick Basic conference is to check your copyright
  785.      notice for alteration using a checksum or CRC.  This is also a good
  786.      idea.  
  787.      
  788.         Patent protection is another form of protection for your program.
  789.      Patent protection offers protection for your IDEA for 17 years.
  790.      However, a patent is much more expensive and harder to obtain than a
  791.      copyright.  A patent is for a useful original and non obvious process,
  792.      machine, manufacture, or composition of matter.  Relating to programs,
  793.      patents will apply to algorithms or other parts of your program.  You
  794.      cannot patent a program itself.  If you can get it, the patent
  795.      provides some of the most airtight protection available.  You have
  796.      exclusive rights to your idea for 17 years.   You cannot reverse
  797.      engineer a patent as you can a copyright.  However, you can invent
  798.      something similar that does not infringe on the patent.  This
  799.      protection comes at a price. You must provide FULL disclosure so that
  800.      anyone skilled in the art may recreate your invention.  To apply for a
  801.      patent on software, you should seek the advice of a Patent Attorney or
  802.      Agent.   A Patent Attorney is a lawyer who has additional technical
  803.      skills and passed a special examination to be admitted to practice
  804.      before the Patent Office.  A Patent agent is a skilled professional
  805.      such as an engineer who has also passed an examination and is also
  806.      permitted to practice before the Patent Office.  Software patents are
  807.      a very new field and the Patent office will be inclined to deny your
  808.      patent.  You will need a skilled person to explain what to patent and
  809.      how to draw up your patent for maximum protection.  Also be prepared
  810.      to spend some serious money, usually several thousand dollars.  It is
  811.      impossible to give an exact dollar amount but it is worthwhile to
  812.      mention that the inventor who recently obtained the patent on
  813.      microprocessor chip design took 20 YEARS AND 2 LAWSUITS to get his
  814.      
  815.      The QBNews                                                     Page 12
  816.      Volume  2, Number  1                                 February 28, 1991
  817.  
  818.      patent application approved. Another concern is that after 17 years,
  819.      you have no protection. Anyone can use an expired patent without
  820.      paying you compensation.  Like a copyright, patent law is generally
  821.      enforced as a civil matter.  You must show that the person used your
  822.      idea and infringed on a claim in your patent.  Another popular defense
  823.      is to claim that your patent is not valid.  It can and has worked so
  824.      be careful.  This is where a patent attorney or agent is invaluable.  
  825.      
  826.           If you have a business, you may develop a trademark.  This is 
  827.      a distinctive word or mark used to identify your business.  The 
  828.      most common example in the computer business is the word IBM(tm).  The
  829.      Apple symbol is also a trademark.  The trademark is used to identify
  830.      your business and cannot be used by others in a deceptive manner.  For
  831.      example, I would not suggest naming your company MicroSoftware, unless
  832.      you would like to meet Bill Gates in court.  The main point to
  833.      remember is that Trademarks are created by use.  A trademark is
  834.      registered by the Patent office, properly called the Patent and
  835.      Trademark office.  Some states also permit trademark registration.
  836.      Registration is valid for 20 years and is renewable as long as you
  837.      continue to use it.  To get a federal trademark, you must create a
  838.      mark and use it in interstate commerce for one year.  Then you can
  839.      register it with the Federal government.  To register, you should
  840.      contact the Patent and Trademark office for information and fees.
  841.      Surprisingly, this can protect your software.  If someone makes pirate
  842.      copies, you can sue them for misuse of your trademark.  In addition,
  843.      it can protect you from having another company try to mislead
  844.      customers by making a similar product with a similar name.
  845.      
  846.         The last type of protection is much more difficult to quantify.
  847.      Trade Secrets are specialized knowledge or information used in a
  848.      business. The secret can be either the knowledge or the use of common
  849.      knowledge in a specialized manner.  An example would be almost any of
  850.      the BIOS tricks used by people to make their programs better.  This
  851.      would be protected by common law rather than Federal Statute.  This
  852.      means that you may have to sue in state rather than Federal courts.
  853.      This can be one of the best methods of protection possible as there is
  854.      NO time limit on the protection.   To qualify for protection, the
  855.      information first must be a secret.  (Bet that surprised you, didn't
  856.      it.)  This means that if you are asked to write a magazine article on
  857.      your methods you must refuse or else risk your trade secret
  858.      protection.  Likewise, you must clearly state to any employees or
  859.      outside contractors used what is and is not secret, preferably by
  860.      written agreement.  You should also keep the information locked up or
  861.      otherwise secured.  In simple terms, the information must not be
  862.      common knowledge and you must treat it as a secret for trade secret
  863.      protection to apply.  However, this will not protect you if someone
  864.      discovers your secret independently and then decides to publish it.
  865.      
  866.         Let's talk a little about license agreements.  Remember that there
  867.      are two very different cases for license agreements.  In the first
  868.      case, you open the software and find a license agreement inside that
  869.      says by opening the software you have agreed to the license agreement.
  870.      This agreement gives you have almost no rights and the company
  871.      reserves all rights.  In this case lawyers have said and the courts
  872.      
  873.      The QBNews                                                     Page 13
  874.      Volume  2, Number  1                                 February 28, 1991
  875.  
  876.      tend to agree that these agreements MAY not be enforceable.  This is
  877.      still open to question however, meaning you will have to go to court
  878.      in order to get such an opinion.  This would likely cost you much more
  879.      than the software itself.  The second case is a more specialized job,
  880.      say a CAD/CAM or database system involving customization of software
  881.      and continuing support.  As part of your contract you have a license
  882.      agreement spelling out trade secrets and other provisions and the 
  883.      client reviews it and requests some changes, which you negotiate and
  884.      agree to.  In that case, the license agreement is very likely to be
  885.      totally enforceable.  The difference between the two agreements is
  886.      fairness and informed consent.  In simple language, you simply cannot
  887.      hand someone a one sided document and say take it or leave it.  When
  888.      creating a license agreement you should definitely have an attorney,
  889.      as failure to draft it properly can invalidate the entire agreement.
  890.      As a user you should check your state laws as several states have
  891.      passed laws regarding license agreements for mass marketed software.  
  892.      
  893.         Up till now I have tried to be factual and objective.  This last 
  894.      paragraph will still be factual but it will rest on some of my 
  895.      personal experience and contain some of my opinions.  You may 
  896.      agree or disagree, but at least think about some the points I 
  897.      raise.  First, should you protect your work?  If you are working
  898.      as a business then definitely yes!  Your skills and programming 
  899.      are your major assets and failure to protect them is foolish.  
  900.      You should also have an attorney skilled in intellectual property 
  901.      work with you.  This will cost some money. Good attorneys get around
  902.      $100.00/hr and UP in my area.  But it should be considered part of the
  903.      cost of doing business.  If you are doing things as a hobby, then it
  904.      gets more doubtful. Most of the work involved in an idea is the
  905.      implementation. Ideas are not worth very much by themselves.  If
  906.      another company wishes to create an idea similar to yours, they very
  907.      likely will succeed. You can "break" patents and any other form of
  908.      intellectual property protection.  The second reason is that a lawsuit
  909.      is a very difficult undertaking.  I have been slightly involved with a
  910.      some lawsuits in my professional life, and consequently, I get nervous
  911.      even walking past a courthouse.  The fact is that a lawsuit is 
  912.      expensive, although may be able to get a lawyer to take your case on
  913.      contingency fee.  It is also expensive in terms of time. You will also
  914.      have to wait several years for your case to come to trial.  When it
  915.      comes to trial, you may have to spend days or weeks in court.  You
  916.      also may be completely surprised by the outcome of your case.  I'm
  917.      pretty sure that had Ashton Tate and SEA realized the outcome of their
  918.      court cases, they would have been more careful before going to court.
  919.      
  920.         In conclusion, intellectual property protection can protect your
  921.      knowledge and expressions of knowledge.  Unless you have some good
  922.      business sense and skill to go with your knowledge, a copyright or
  923.      patent by itself will not make your rich.  
  924.      
  925.      
  926.      
  927.                             Contact Information 
  928.      
  929.         Here is information for you to contact the appropriate government 
  930.      
  931.      The QBNews                                                     Page 14
  932.      Volume  2, Number  1                                 February 28, 1991
  933.  
  934.      offices for copyright and patent information.
  935.      
  936.                              Copyright Office
  937.      
  938.         There are two phone numbers for the copyright office.  One to 
  939.      order copyright information and another to speak with  a copyright
  940.      information specialist who will help you with information.  Bear in
  941.      mind that they are not an enforcement agency and they are not
  942.      attorneys so they will not give any legal opinions.  Also remember
  943.      that the fee is $20.00 up from $10.00.
  944.      
  945.      Order Line:  202 707-9100
  946.      Information Line:  202 479-0700
  947.      Start with circulars 1, 31, 61, and form TX. 
  948.      Address:  Register of Copyrights
  949.                Copyright Office
  950.                Library of Congress
  951.                Washington, D.C. 20559
  952.      
  953.                         Patent and Trademark Office
  954.      
  955.         I tried to contact the Patent office for this article but could 
  956.      not make contact with them.  If you want to talk to them, good luck.
  957.      They have their major offices in Arlington Va.
  958.      Phone Number:  703 557-3341
  959.      Address:  Commissioner of Patents and Trademarks
  960.                Washington, D.C. 20231
  961.      
  962.      
  963.      
  964.                                Bibliography
  965.      
  966.         Here is a list of books and other sources I have used to prepare 
  967.      this article.  This is not a complete list but is a good stating 
  968.      point.  
  969.      
  970.                                    Books
  971.      
  972.      The Incredible Secret Money Machine 
  973.      By:  Don Lancaster,  Published by:  Howard Sams & Company.
  974.      
  975.      What   everybody  should  know  about  patents   trademarks   and  
  976.      copyrights  
  977.      By:  Donald M Dible,editor  Published by:  Entrepreneur
  978.      
  979.      The  legal  guide to computer software  protection;  a  practical 
  980.      handbook on copyrights, trademarks, publishing, and trade secrets
  981.      By:  Thorne D. Harris
  982.      
  983.      Spectacular Computer Crimes
  984.      By:  Buck Bloombecker  Published by: Dow Jones-Irwin
  985.      
  986.                              Magazine Articles
  987.      
  988.      
  989.      The QBNews                                                     Page 15
  990.      Volume  2, Number  1                                 February 28, 1991
  991.  
  992.      Little Quarterdeck Throws Its Weight Around
  993.      Business Week June 19, 1989,  By:  Patrick Cole and Deidre Depke 
  994.      
  995.      Protecting  Intellectual  Property Rights Abroad:   Pointers  for 
  996.      U.S. Exporters
  997.      Business America  Nov 21, 1988,  By:  Guy C. Smith
  998.      
  999.      Clamp a Lid on Company Secrets
  1000.      Nation's Business July 1988,  By:  Jane Easter Bahls
  1001.      
  1002.      Who Owns the Copyrights?
  1003.      Byte  April 1990,  By:  William T. McGrath
  1004.      
  1005.      The Case Against Patents
  1006.      Radio Electronics January 1991,  By:  Don Lancaster
  1007.      
  1008.                               BBS Information
  1009.      
  1010.         Several  Files were downloaded from EXEC-PC (414)  789-4210,  Bix 
  1011.      (617)  861-9767 and Genie for research on this  article.   Search 
  1012.      for Copyright, patent and Trademark and you will find the current 
  1013.      files dealing with these subjects.
  1014.      
  1015.      *********************************************************************
  1016.      David Postler is a Field Service Engineer working on NC and CNC
  1017.      machine tools. He can be reached in the Quik_Bas echo in Fidonet or in
  1018.      care of this newsletter.
  1019.      *********************************************************************
  1020.      
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.      The QBNews                                                     Page 16
  1047.  
  1048.  
  1049.      ----------------------------------------------------------------------
  1050.                                 S w a p   S h o p
  1051.      ----------------------------------------------------------------------
  1052.  
  1053.      
  1054.         All of the following code came from the QUIK_BAS National
  1055.      Conference available from FidoNet. If you are interested in receiving
  1056.      this conference, ask the sysop of your local Fido BBS about picking
  1057.      it up. Inquiries about echo feeds should be sent to Fabian Gordon
  1058.      at 1:107/323.
  1059.      
  1060.      ---------------------------------------------------------------------
  1061.      
  1062.      From:   Richard Randles
  1063.      To:     Mike Welch
  1064.      Subj:   Re: Bit of this, bit of that
  1065.      
  1066.      MW> First, I want to again thank you for the bit check routine.  I
  1067.      MW> finally got around to checking out all the responses I received.
  1068.      MW> Sometimes it's nice, and sometimes it's not so nice, but it is
  1069.      MW> always interesting to see how many DIFFERENT ways one thing can be
  1070.      MW> handled in a program!
  1071.      
  1072.      That's what I like about it.  It doesn't matter how experienced you
  1073.      are, sooner or later you'll see someone do something that works better
  1074.      than what you thought was the best.
  1075.      
  1076.      MW> I received about 8 different ideas, of those that actually worked 
  1077.      MW> (grin) I liked yours the best.   Seemed the easiest way to get the 
  1078.      MW> answer.  
  1079.      
  1080.      It's a middle of the road routine.  Simple but not as speedy as it
  1081.      could be.  I threw it in there for variety.
  1082.      
  1083.      MW> My question for you, Richard, is sort of two fold:
  1084.      MW>  
  1085.      MW> 1.  What are you doing with GetBit% = Work& AND 1?
  1086.      MW>     Why is the Work& AND 1 necessary?  Duh?
  1087.      
  1088.      It removes any higher order bits that may remain.  ie:  if you pass 9
  1089.      (1001) and check bit 2, Work& would contain 2 (10).  Anding with 1
  1090.      then turns off all other bits except the first one.
  1091.      
  1092.      MW> 2.  Now, fine.  I can read bits in a word.  Goodie.  Okay, 
  1093.      MW>     how about a similar routine that SETs bits in a word!
  1094.      MW>  
  1095.      MW> Am I pushy, or what?  (tapping foot)... <grin>
  1096.      
  1097.      Oh, and I suppose you're going to be difficult and want it in BASIC
  1098.      instead of assembler?  ;)  I'll give you both.  The assembler version
  1099.      of SetBit took a lot less time to write than the BASIC one because of
  1100.      the problems of handling negative (sign bit set) values in BASIC.
  1101.      
  1102.      See the next message for the assember versions of both routines.
  1103.      
  1104.      The QBNews                                                     Page 17
  1105.      Volume  2, Number  1                                 February 28, 1991
  1106.  
  1107.      
  1108.      '------------------- Tear Here ---------------------
  1109.      
  1110.      DECLARE FUNCTION GetBit% (Word%, BPos%)
  1111.      DECLARE SUB SetBit (Word%, BPos%, OnOff%)
  1112.      
  1113.      FUNCTION GetBit% (Word%, BPos%)
  1114.         Bit& = 1
  1115.         FOR i% = 1 TO BPos%
  1116.            Bit& = Bit& + Bit&
  1117.         NEXT i%
  1118.         GetBit% = -((Word% AND Bit&) > 0)
  1119.      END FUNCTION
  1120.      
  1121.      SUB SetBit (Word%, BPos%, OnOff%)
  1122.         Bit& = 1
  1123.         FOR i% = 1 TO BPos%                       'Make mask
  1124.            Bit& = Bit& + Bit&
  1125.         NEXT i%
  1126.         IF Bit& > 32767 THEN Bit% = Bit& - 65536 ELSE Bit% = Bit&
  1127.         IF OnOff% THEN
  1128.            Word% = Word% OR Bit%                  'Turn bit on
  1129.         ELSE
  1130.            Word% = Word% AND NOT Bit%             'Turn bit off
  1131.         END IF
  1132.      END SUB
  1133.      ----------------------------------------------------------------------
  1134.  
  1135.      
  1136.      From:   Rick Cooper
  1137.      To:     Mike Welch
  1138.      Subj:   Reversing Color Attributes
  1139.      
  1140.      FUNCTION MakeReverse% (attrb)
  1141.      '=====================================================================
  1142.      ' Syntax : Attribute = MakeReverse%(Attrbute)
  1143.      ' Will Reverse Attribute and Maintain Blink and High Intensity Bits.
  1144.      ' When You Reverse An Attribute With High Intensity Bit Set,The Former
  1145.      ' Background Color Will Become A High Intensity Forground Color.
  1146.      '=====================================================================
  1147.       
  1148.      forground = (attrb AND &HF)                   'Get Forground Color
  1149.      background = ((attrb AND &HF0) / &H10)        'Get Background Color
  1150.       
  1151.      oattrb = attrb                                'Save Original Attribute
  1152.       
  1153.      attrb = ((16 * forground) + (background))     'Make New Attribute
  1154.       
  1155.      '=====================================================================
  1156.      ' Check The New Attribute Against The Old To See If Intensity And
  1157.      ' Blink Bits Agree And Take Needed Action
  1158.      '=====================================================================
  1159.       
  1160.      IF (oattrb AND 128) <> 128 AND (attrb AND 128) = 128 THEN
  1161.      attrb = (attrb XOR 128) + 8
  1162.      ELSEIF (oattrb AND 128) = 128 AND (attrb AND 128) <> 128 THEN
  1163.      
  1164.      The QBNews                                                     Page 18
  1165.      Volume  2, Number  1                                 February 28, 1991
  1166.  
  1167.      attrb = (attrb XOR 128) - 8
  1168.      END IF
  1169.       
  1170.      MakeReverse% = attrb
  1171.       
  1172.      END FUNCTION
  1173.      ----------------------------------------------------------------------
  1174.  
  1175.      
  1176.      From:   Monte Ferguson
  1177.      To:     Tony Mace
  1178.      Subj:   Detecting a Multi-Tasker
  1179.      
  1180.      > Question:  Does anyone know how using QuickBasic to detect if a
  1181.      > multitasker is running.
  1182.      
  1183.       I wrote something to detect Desqview (and return a version number):
  1184.      
  1185.      ------------------------------> clip here <---------------------------
  1186.      DECLARE FUNCTION DVVers! ()
  1187.      
  1188.      DEFINT A-Z
  1189.      
  1190.      TYPE RegType
  1191.         AX AS INTEGER
  1192.         Bx AS INTEGER
  1193.         CX AS INTEGER
  1194.         DX AS INTEGER
  1195.         BP AS INTEGER
  1196.         SI AS INTEGER
  1197.         DI AS INTEGER
  1198.         FLAGS AS INTEGER
  1199.         DS AS INTEGER
  1200.         ES AS INTEGER
  1201.      END TYPE
  1202.      
  1203.      DIM SHARED InRegs AS RegType, OutRegs AS RegType
  1204.      
  1205.      CLS
  1206.      DV! = DVVers!
  1207.      IF DV! = 0 THEN
  1208.         PRINT "DESQview is currently NOT running."
  1209.      ELSE
  1210.         PRINT USING "You are running under DESQview version #.##"; DV!
  1211.      END IF
  1212.      
  1213.      END
  1214.      
  1215.      FUNCTION DVVers!
  1216.      
  1217.         InRegs.CX = &H4445   ' An invalid date... (= "DESQ")
  1218.         InRegs.DX = &H5351
  1219.         InRegs.AX = &H2B01      ' DOS Set Date function
  1220.         CALL interrupt(&H21, InRegs, OutRegs)
  1221.         IF (OutRegs.AX AND 255) = 255 THEN
  1222.            DV.Vers = 0
  1223.      
  1224.      The QBNews                                                     Page 19
  1225.      Volume  2, Number  1                                 February 28, 1991
  1226.  
  1227.         ELSE
  1228.            DV.Vers! = ((OutRegs.Bx AND &HFF00) / 256) + _
  1229.               (OutRegs.Bx AND 255) / 100
  1230.         END IF
  1231.         DVVers! = DV.Vers!
  1232.      
  1233.      END FUNCTION
  1234.      ----------------------------------------------------------------------
  1235.  
  1236.      
  1237.      From:   Rick Cooper
  1238.      To:     Tim Kilgor
  1239.      Subj:   File Exist
  1240.      
  1241.      I Have Included The Routine For Setting The File's Attribute But To
  1242.      Check For A File's Existance You Only Need Use The "Get Attribute"
  1243.      routine. Its Only About 12 or 13 Lines Of Code.
  1244.       
  1245.      '*********************************************************************
  1246.      ' This Code Is QB 4.5 For PSD7 Change VARSEG To SSEG
  1247.      '
  1248.      ' I have Included Functions For Getting And Setting File Attributes
  1249.      ' You Should Always Get The Attribute First So That You Only Toggle
  1250.      ' The Attribute You Want And Leave Any Other Attributes Alone.
  1251.      ' Both Functions Return the Same Error Codes, GetFileAttribute%
  1252.      ' Returns The Error In ReturnCode% And The Attribute In It's Name
  1253.      ' While Function SetFileAttribute% Returns The Error Code In It's
  1254.      ' Name.
  1255.      ' Error Codes Are As Follows:
  1256.      '       1 = Invalid Function (Networks Only)
  1257.      '       2 = File Not Found
  1258.      '       3 = Path Not Found
  1259.      '       5 = Access Denied (NetWorks Only)
  1260.      ' Have You Guessed That GetFileAttribute Would Be Ideal For Checking
  1261.      ' For A Path Or File's Existance??? Only 13 Lines Of Code.
  1262.      ' Usage:
  1263.      '       Attribute% = GetFileAttribute% (FileName$,ReturnCode%)
  1264.      '               FileName$ Can Include Full Path Names
  1265.      '               ReturnCode% Will Be One Of The Above Or 0
  1266.      '               The File Attribute Is Returned In The Function Name
  1267.      '
  1268.      '      ErrorCode% = SetFileAttribute%(FileName$,FileAttribute%,Attrb$)
  1269.      '               FileName$ Can Include Full Path Names
  1270.      '               FileAttribute% Is The Attribute You Wish To Change
  1271.      '               Attrb$ Is One Or All Of The Following Characters
  1272.      '                       A = Archive
  1273.      '                       S = System
  1274.      '                       H = Hidden
  1275.      '                       R = Read Only
  1276.      '               Will Accept Characters Of Any Case
  1277.      '
  1278.      ' I Have Included A SIMPLE Demo With No Error Checking Routine....
  1279.      ' And It Will' Continue To Toggle The Attribute As Desired Until You
  1280.      ' Press Enter Or Escape.
  1281.      '*********************************************************************
  1282.      DECLARE FUNCTION GetFileAttribute% (FileName$, ReturnCode%)
  1283.      
  1284.      The QBNews                                                     Page 20
  1285.      Volume  2, Number  1                                 February 28, 1991
  1286.  
  1287.      DECLARE FUNCTION SetFileAttribute% (FileName$,FileAttribute%, Attrib$)
  1288.      '$INCLUDE: 'qb.bi'
  1289.       
  1290.      FileName$ = COMMAND$                            'Get The Name Easy
  1291.       
  1292.      IF FileName$ = "" THEN
  1293.              INPUT "Enter file name "; FileName$     'Or get it direct
  1294.      END IF
  1295.       
  1296.      CLS                                             'Clear the screen
  1297.       
  1298.      start:                                          'OH GOD A LABEL!!!!
  1299.       
  1300.      Attrb$ = STRING$(4, 95)                         'Set up the blanks
  1301.      FAttrb% = GetFileAttribute%(FileName$, RC%)     'Get the attribute
  1302.                                                    'And set string properly
  1303.       
  1304.      IF (FAttrb% AND 1) = 1 THEN MID$(Attrb$, 1, 1) = "R"
  1305.      IF (FAttrb% AND 2) = 2 THEN MID$(Attrb$, 2, 1) = "H"
  1306.      IF (FAttrb% AND 4) = 4 THEN MID$(Attrb$, 3, 1) = "S"
  1307.      IF (FAttrb% AND &H20) = &H20 THEN MID$(Attrb$, 4, 1) = "A"
  1308.       
  1309.      mess$ = FileName$ + "  " + Attrb$          ' Show the name and current
  1310.                                                      ' file attribute
  1311.      LOCATE 1, 1
  1312.      PRINT mess$                                     'And print it
  1313.       
  1314.      IF RC% = 0 THEN                                'Check for error and if
  1315.                                                      'none go on and toggle
  1316.       
  1317.      Ans$ = INPUT$(1)                              'Get attribute to toggle
  1318.                                                      'or request to exit
  1319.       
  1320.      IF Ans$ = CHR$(27) OR Ans$ = CHR$(13) THEN SYSTEM
  1321.              RC% = SetFileAttribute%(FileName$, FAttrb%, Ans$)     'TOGGLE
  1322.              Ans$ = ""                                             'Clear
  1323.              GOTO start                              'OH GOD A GOTO!!!!!
  1324.      ELSE
  1325.              PRINT "Error #" + LTRIM$(STR$(RC%))   'Yep, and error so print
  1326.                                                      'code and exit
  1327.              SYSTEM
  1328.      END IF
  1329.       
  1330.      FUNCTION GetFileAttribute% (FileName$, ReturnCode%)
  1331.      '*********************************************************************
  1332.      'Now To The Meat Of Things... This Will Quickly Tell If A File Exists
  1333.      'Or Not.
  1334.      '*********************************************************************
  1335.       
  1336.      DIM InRegs AS RegTypeX, OutRegs AS RegTypeX     'Dimension Register
  1337.                                                      'Types
  1338.      FileToSet$ = FileName$ + CHR$(0)                'Make ASCIIZ String
  1339.                                                      'From File Name
  1340.      ReturnCode% = 0                                 'Zero Return Code
  1341.      
  1342.      The QBNews                                                     Page 21
  1343.      Volume  2, Number  1                                 February 28, 1991
  1344.  
  1345.       
  1346.      InRegs.ax = (256 * &H43) + &H0                  'Set Function Number
  1347.      InRegs.ds = VARSEG(FileToSet$)                  'Pass Segment Of Name
  1348.      InRegs.dx = SADD(FileToSet$)                    'Pass Offset Of Name
  1349.      CALL INTERRUPTX(&H21, InRegs, OutRegs)          'Call Interrupt 21
  1350.       
  1351.      IF (OutRegs.flags AND 1) = 0 THEN               'Is There Any Errors?
  1352.       
  1353.              GetFileAttribute% = OutRegs.cx         'Nope..Return Attribute
  1354.      ELSE
  1355.              ReturnCode% = OutRegs.ax                'Yep! Pass Error Code
  1356.      END IF
  1357.      END FUNCTION
  1358.       
  1359.       
  1360.      FUNCTION SetFileAttribute% (FileName$, FileAttribute%, Attrib$)
  1361.       
  1362.      DIM InRegs AS RegTypeX, OutRegs AS RegTypeX    'Dimension Register
  1363.                                                     'Types
  1364.      Attrib$ = UCASE$(Attrib$)                      'Make Sure It's
  1365.                                                     'Upper Case
  1366.      FileToSet$ = FileName$ + CHR$(&H0)             'Convert Name to
  1367.                                                     'ASCIIZ
  1368.      FOR i = 1 TO LEN(Attrib$)                      'Toggle All The
  1369.                                                     'Any Selected
  1370.      SELECT CASE MID$(Attrib$, i, 1)                'Attributes
  1371.       
  1372.      CASE IS = "R"
  1373.              FileAttribute% = FileAttribute% XOR &H1 'Toggle Read Only
  1374.      CASE IS = "H"
  1375.              FileAttribute% = FileAttribute% XOR &H2 'Toggle Hidden
  1376.      CASE IS = "S"
  1377.              FileAttribute% = FileAttribute% XOR &H4 'Toggle System
  1378.      CASE IS = "A"
  1379.              FileAttribute% = FileAttribute% XOR &H20'Toggle Archive
  1380.      END SELECT
  1381.      NEXT i
  1382.      
  1383.      InRegs.ax = (256 * &H43) + &H1                  'Load Set Function
  1384.      InRegs.cx = FileAttribute%                      'Attribute To Set
  1385.      InRegs.ds = VARSEG(FileToSet$)                  'Pass Segment
  1386.      InRegs.dx = SADD(FileToSet$)                    'Pass Offset
  1387.      CALL INTERRUPTX(&H21, InRegs, OutRegs)          'Call Interrupt 21
  1388.      
  1389.      IF (OutRegs.flags AND 1) <> 0 THEN              'Is There An Error?
  1390.              SetFileAttribute% = OutRegs.ax          'Yep! Pass Error
  1391.      ELSE                                            'Nope..Pass Zero
  1392.              SetFileAttribute% = 0
  1393.      END IF
  1394.      
  1395.      END FUNCTION
  1396.      ----------------------------------------------------------------------
  1397.  
  1398.      
  1399.      From:   Keith Rolland
  1400.      To:     All
  1401.      
  1402.      The QBNews                                                     Page 22
  1403.      Volume  2, Number  1                                 February 28, 1991
  1404.  
  1405.      Subj:   Ok Mike... :)
  1406.      
  1407.      'PROGRAMINFO.BAS, QuickBasic SUBroutine, 82 lines
  1408.      'For the use of all QB users everywhere.
  1409.      'Keith Rolland 1:321/109.2@FidoNet
  1410.      
  1411.      '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1412.      ' declare sub ProgramInfo (ProgramName$, CommandTail$, DosVerHi%,_
  1413.      '                        DosVerLo%, CurrentDir$, Path$, Environment$)
  1414.      '
  1415.      ' ProgramName$ = the full name of the currently running program
  1416.      ' CommandTail$ = anything else that was on the command line, case
  1417.      '  preserved
  1418.      ' Environment$ = the full text of the environment, each separated by
  1419.      '  chr$(255)
  1420.      ' CurrentDir$ = the current directory, which may be different than
  1421.      '  Path$
  1422.      ' Path$ = the full path where the program is, as in "C:\BASIC\PROGS"
  1423.      ' DosVerHi% = the major number of DOS, as in "3"
  1424.      ' DosVerLo% = the minor number of DOS, as in "21"  (for DOS 3.21)
  1425.      ' This routine should be used before any disk activity is performed,
  1426.      ' because the default 128-byte DTA (disk transfer area) is the
  1427.      ' CommandTail$ area.
  1428.      '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1429.      
  1430.      '$include: '\qb\lib\qb.bi'
  1431.      
  1432.      sub ProgramInfo (ProgramName$, CommandTail$, DosVerHi%,_
  1433.                       DosVerLo%, CurrentDir$, Path$, Environment$)
  1434.      
  1435.      Environment$ = "" : ProgramName$ = "" : Path$ = "" : CommandTail$ = ""
  1436.      dim reg as RegTypeX
  1437.      
  1438.      reg.ax = &H3000
  1439.      interruptx &H21, reg, reg
  1440.      DosVerLo% = (reg.ax \ 256)
  1441.      DosVerHi% = (reg.ax mod 256)
  1442.      
  1443.      reg.ax = &H1900
  1444.      interruptx &H21, reg, reg
  1445.      Drive$ = chr$((reg.ax and &Hff) + 65) + ":\"
  1446.      reg.dx = 0
  1447.      reg.ax = &H4700
  1448.      tmp$ = space$(64)
  1449.      reg.ds = varseg(tmp$)
  1450.      reg.si = sadd(tmp$)
  1451.      interruptx &H21, reg, reg
  1452.      CurrentDir$ = Drive$ + left$(tmp$, instr(tmp$, chr$(0)) - 1)
  1453.      
  1454.      
  1455.      reg.ax = 25088
  1456.      interruptx &H21, reg, reg
  1457.      def seg = reg.bx
  1458.      EnvLo% = peek(&H2c)
  1459.      
  1460.      The QBNews                                                     Page 23
  1461.      Volume  2, Number  1                                 February 28, 1991
  1462.  
  1463.      EnvHi% = peek(&H2d)
  1464.      CmdTailLen% = peek(&H80)
  1465.      
  1466.      for tmp% = &H81 to ((&H81 + CmdTailLen%) - 1)
  1467.      CommandTail$ = CommandTail$ + chr$(peek(tmp%))
  1468.      next tmp%
  1469.      
  1470.      def seg = EnvLo% + (EnvHi% * 256)
  1471.      Pointer% = 0
  1472.      do until peek(Pointer%) = 0
  1473.              do until peek(Pointer%) = 0
  1474.                      Environment$ = Environment$ + chr$(peek(Pointer%))
  1475.                      Pointer% = Pointer% + 1
  1476.              loop
  1477.              Environment$ = Environment$ + chr$(255)
  1478.              Pointer% = Pointer% + 1
  1479.      loop
  1480.      
  1481.      Pointer% = Pointer% + 3
  1482.      do until peek(Pointer%) = 0
  1483.              ProgramName$ = ProgramName$ + chr$(peek(Pointer%))
  1484.              Pointer% = Pointer% + 1
  1485.      loop
  1486.      
  1487.      PathLen% = len(ProgramName$)
  1488.      for Pointer% = PathLen% to 1 step -1
  1489.              tmp$ = mid$(ProgramName$, Pointer%, 1)
  1490.              if tmp$ = "\" then
  1491.                      Path$ = left$(ProgramName$, (PathLen% - Pointer% - 2))
  1492.                      ProgramName$ = mid$(ProgramName$, Pointer% + 1)
  1493.                      exit for
  1494.              end if
  1495.      next Pointer%
  1496.      def seg
  1497.      end sub
  1498.      ----------------------------------------------------------------------
  1499.  
  1500.      
  1501.      From:   James Young
  1502.      To:     All
  1503.      Subj:   Playing Around With Random Numbers
  1504.      
  1505.      If anyone is interested in experimenting with random number
  1506.      generators, you might try the following.  The linear congruential
  1507.      method of generating pseudo-random sequences has been widely studied
  1508.      and analyzed for years.  This method can be written like this:
  1509.      
  1510.           FOR j = 2 to N
  1511.              a(j) = (a(j-1) * B + 1) MOD M
  1512.           NEXT
  1513.      
  1514.      If a(1) contains some arbitrary number (the "seed"), this code
  1515.      fragment will fill up an array with N random numbers.  To get a new
  1516.      random number, take the previous one, multiply by a constant B, add 1,
  1517.      and take the remainder when divided by a second constant M.  The
  1518.      result will be an integer between 0 and M-1.
  1519.      
  1520.      The QBNews                                                     Page 24
  1521.      Volume  2, Number  1                                 February 28, 1991
  1522.  
  1523.       
  1524.      The analyses of this formula have provided some guidelines for
  1525.      selecting B and M.  First, M should be large.  It is normally
  1526.      convenient to make M a power of 2 or 10.  Second, B shouldn't be too
  1527.      large or too small; a safe choice is to use a number with one digit
  1528.      less than M.  Third, B should be an arbitrary constant with no
  1529.      particular pattern in its digits EXCEPT that it should end with the
  1530.      three digits x21 with x being an even digit.  (This last requirement
  1531.      is peculiar, but it prevents some bad sequences which have been found
  1532.      by analysis.)  Any seed will work.  
  1533.      
  1534.      Some combinations of B, M, and a(1) will cause very short cycle
  1535.      sequences to be generated.  For example, B=19, M=381, and a(1)=0 will
  1536.      generate the sequence 0,1,20,0,1,20,....
  1537.      
  1538.      Implementing this in BASIC requires a little fiddling because the
  1539.      multiplication a*b usually causes an overflow.  This can be overcome
  1540.      by breaking the multiplication up into pieces and tossing out the
  1541.      pieces which cause the overflow since we are only interested in some
  1542.      of the right-hand digits. 
  1543.      
  1544.      This example uses a seed of 1234, an M of 10000, and a B of 7821.  The
  1545.      seed is broken into p1 and p0, and B is broken into q1 and q0.  M1 is
  1546.      selected such that M1*M1=M.
  1547.      
  1548.      One other problem with this method is that the right-most digits are
  1549.      usually not particularly random.  This example gets rid of the two
  1550.      right hand digits.
  1551.      
  1552.      DEFINT A-Z
  1553.      a = 1234                ' this is the "seed'
  1554.      FOR j = 1 to 100        ' generate 100 random numbers
  1555.         M = 10000            ' see text
  1556.         M1 = 100             ' M1 * M1 = M
  1557.         b = 7821             ' see text (note last 3 digits)
  1558.         p1 = a \ M1          ' this line and the next 5 lines
  1559.         p0 = a MOD M1        '    get around the problem of
  1560.         q1 = B \ M1          '    overflow
  1561.         q0 = B MOD M1
  1562.         c = (((p0 * q1 + p1 * q0) MOD M1) * M1 + p0 * q0) MOD M
  1563.         a = (c + 1) MOD M  ' replace the old random number with the new one
  1564.         g = a \ M1           ' throw away the last 2 digits
  1565.         PRINT g              ' this is our "random" number
  1566.      NEXT
  1567.           Volume  2, Number  1                                 February 28, 1991
  1568.  
  1569.  
  1570.  
  1571.      ----------------------------------------------------------------------
  1572.                       G r a p i c a l l y   S p e a k i n g
  1573.      ----------------------------------------------------------------------
  1574.  
  1575.      Reading Print Shop Graphics in QuickBASIC by Michael Welch
  1576.      
  1577.           Graphics have always impressed me, even back in the days when
  1578.      SCREEN 2 was considered "high resolution."  Recently, Earl Montgomery
  1579.      revitalized my interest in a QuickBASIC script that Ryan Snodgrass
  1580.      submitted to the Fido QUIK_BAS echo.  I thought this program would
  1581.      display Print Master graphics in SCREEN mode 1.  Try as I did, I could
  1582.      not get the program to work!  In this, my second attempt at
  1583.      understanding the file format, I realized that Ryan's routine was
  1584.      designed to work only with Print SHOP icons, and I learned some other
  1585.      very interesting things in the process.
  1586.      
  1587.           The following discussion assumes the reader understands the
  1588.      concept of data types, has a full grasp of file I/O, and has some
  1589.      understanding of graphics programming.  The aim of this article is to
  1590.      discuss a popular graphic file format.  For theory and syntax to the
  1591.      QuickBASIC language, please refer to the beginner's column.
  1592.      
  1593.           Print Master and Print Shop icons are 88 rows by 52 columns in
  1594.      dimension.  In this discussion I will use the term "row" and "column"
  1595.      to refer to the X and Y coordinates, respectively, of what is actually
  1596.      a pixel [pixel, as the reader may know, stands for "picture element"].
  1597.      Considering the 88x52 structure, therefore, one might expect a single
  1598.      Print Shop icon record to require 88 * 52 bytes, or 4576 bytes each.
  1599.      After looking over his code, however, I noticed that Ryan processed
  1600.      572 bytes for each icon read from the file.  How could this be?
  1601.      
  1602.           PM and PS graphics are BIT CODED, and quite elegantly so. 
  1603.      Remember that PS and PM icons are monochrome; the only colors used are
  1604.      black and white, or if you will, OFF and ON.  This BINARY structure
  1605.      makes it quite possible to code 8 pixels into 1 byte. In summary, the
  1606.      files break down as:  88 pixels * 52 pixels = 4576 pixels, and 4576
  1607.      divided by 8 [the number of bits in a byte] = 572 bytes.  This reduces
  1608.      the potential size of a PS/PM file by a factor of 800%!  Quite a
  1609.      compression, I would say!  Too, it offers the QB programmer a
  1610.      beginning for developing his/her own screen compression algorithm!
  1611.      
  1612.           Thanks to a discovery by your QBNews Editor, PSHOP.BAS also shows
  1613.      how to read The New Print Shop graphic files.  Actually, the format of
  1614.      both the old and the new PS is exactly the same.  The difference lies
  1615.      in a 10 byte header in the beginning of each graphic file (not
  1616.      record).  To read The New Print Shop graphics, simply use SEEK, or as
  1617.      I have done in PSHOP, INPUT$(10, #Buff), to skip the first 10 bytes of
  1618.      the file.
  1619.      
  1620.           I originally wrote PSHOP.BAS to be compiled with Crescent's PDQ
  1621.      and to run only on VGA systems.  Because PDQ does not support any
  1622.      graphics itself, and since graphics are quite easy to accomplish in
  1623.      VGA systems by simply writing directly to video memory [see Larry
  1624.      Stone's article in the QBNews about reading video memory directly with
  1625.      
  1626.      The QBNews                                                     Page 25
  1627.      Volume  2, Number  1                                 February 28, 1991
  1628.  
  1629.      PEEK:  Vol 1, Num 5], I decided to use POKE to display the icons.  As
  1630.      requested by your Editor, however, I have redesigned PSHOP to use PSET
  1631.      and SCREEN 2 ("high resolution" CGA mode).  Also, you may test run
  1632.      PSHOP.BAS in the QuickBASIC/PDS environment.  To use a different
  1633.      screen mode, simply change the SCREEN statement to match your hardware
  1634.      configuration.  As you change screen modes, you will likely also be
  1635.      changing the screen dimensions.  The coordinates used in PSHOP as it
  1636.      stands will work only for screens having the 640x200 dimension.
  1637.      
  1638.           Finally, I have included two different PSET statements and two
  1639.      different POKE statements in the source file, the latter being
  1640.      commented out for VGA/PDQ users.  In both cases, the first statement
  1641.      will print the icon on the upper left corner of the screen, and the
  1642.      second will print the picture in the center of the screen.  Consider
  1643.      the following code segment from PSHOP:
  1644.      
  1645.           PSET (x% + 7 - k%, y%), p%              ' left of any screen
  1646.           PSET (x% + 7 - k% + 276, y% + 74), p%   ' Center on SCREEN 2
  1647.      
  1648.           The second statement centers the image on the screen. Obviously,
  1649.      this could be simplified to PSET(x% - k% + 283, y% + 74), p%.  I coded
  1650.      this portion specifically to demonstrate what I have done to center
  1651.      the image.  The reader's challenge is to determine how I formulated
  1652.      the values of 276 and 74 in the forgoing example.
  1653.      
  1654.           I commented PSHOP.BAS heavily, realizing that in-line comments
  1655.      are much more useful than mentioning significant information in an
  1656.      article, away from the actual code.  Therefore, to understand how
  1657.      PSHOP.BAS works, the reader should examine the code.
  1658.      
  1659.           I am including the source code in PSHOP.BAS and two Print Shop
  1660.      example graphic files.  BOB.DAT contains a few public domain Print
  1661.      Shop graphic icons in the "old format." NEWPS.DAT contains a few
  1662.      pieces of art from The New Print Shop. When loading NEWPS.DAT, be sure
  1663.      to include the /n parameter following the filename such that PSHOP
  1664.      will know to skip the 10 byte header explained earlier.  Look for
  1665.      these files in PSHOP.ZIP.
  1666.      
  1667.           Another point worthy of discussion involves a difference between
  1668.      Print Shop's and Print Master's file structure.  Print Shop files are
  1669.      structured exactly as suggested.  They are bit coded to 572 bytes in a
  1670.      RANDOM type fashion (i.e., the icon data are contiguous).  While I
  1671.      cannot explain the structural difference between PS and PM files, I
  1672.      did make a significant observation. Primarily, the difference lies in
  1673.      the fact that PM files have some sort of delimiter (delimiters are
  1674.      used, for example, in Turbo Pascal files to signify the end of a
  1675.      record).  This delimiter can be defined as:  Delimiter$ = CHR$(11) +
  1676.      CHR$(52) + CHR$(88).  I discovered this Delimiter$ pattern to occur
  1677.      the same number of times as there were icons.  For example, if the PM
  1678.      library has 100 icons, it also has 100 Delimiter$'s.  However, more
  1679.      information is needed to properly convert Print Master graphics to a
  1680.      Print Shop format.  Delimiter$ does not occur in a fixed order, and
  1681.      reading PM graphic libraries with the PSHOP program will have sporadic
  1682.      results.
  1683.      
  1684.      The QBNews                                                     Page 26
  1685.      Volume  2, Number  1                                 February 28, 1991
  1686.  
  1687.      
  1688.           Now that we all understand the general format of a Print Shop
  1689.      graphic image file, this author would be very interested to see a
  1690.      utility which will convert Print Master files to the more simplified
  1691.      Print Shop format.  Hopefully, in the next issue...?
  1692.      
  1693.      **********************************************************************
  1694.      Mike Welch is a Rehabilitation Science major at the University of
  1695.      Texas Southwestern Medical Center. He is also the "librarian" for
  1696.      QuickSHARE, a free QuickBASIC file distribution service. For more
  1697.      information on QuickSHARE and to contact Mike, please see the article
  1698.      on QuickSHARE in this issue.
  1699.      **********************************************************************
  1700.      
  1701.      [EDITORS NOTE]
  1702.      All files for this article can be found in PSHOP.ZIP.
  1703.      
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.  
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.  
  1720.  
  1721.  
  1722.  
  1723.  
  1724.  
  1725.  
  1726.  
  1727.  
  1728.  
  1729.  
  1730.  
  1731.  
  1732.  
  1733.  
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740.  
  1741.      The QBNews                                                     Page 27
  1742.      Volume  2, Number  1                                 February 28, 1991
  1743.  
  1744.  
  1745.  
  1746.      ----------------------------------------------------------------------
  1747.                         P o w e r   P r o g r a m m i n g
  1748.      ----------------------------------------------------------------------
  1749.  
  1750.      Creating Smaller QB Executables  by T. G. Muench
  1751.      
  1752.         QuickBASIC (QB) is a great product for the price, but it is not
  1753.      exactly known for generating small programs. This article explains
  1754.      how to create smaller stand alone QuickBASIC executables using nothing
  1755.      other than what comes with QB. Hopefully it will help others avoid
  1756.      some of the frustration I encountered learning HOW to accomplish this!
  1757.      
  1758.         As the author of pEDIT, a shareware text editor written in QB 4.5,
  1759.      I needed some way to reduce the size of the executable as pEDIT grew
  1760.      larger and larger. The smallest EXE under QB4.5 is something like 12-
  1761.      15k bytes. This is due mainly to the HUGE amounts of object code
  1762.      linked in after compiling. It turns out that Microsoft's libraries
  1763.      lack (here's a 25-cent word) granularity. This means that whenever you
  1764.      link in a procedure you are probably getting the code for several
  1765.      other procedures. Sometimes this added code is insignificant; some-
  1766.      times it is HUGE.
  1767.      
  1768.         An example is the HEX$() function. Whenever you use HEX$() you are
  1769.      linking in a library module named 'hexoct' which contains three entry
  1770.      points: B$FBIN (there is no BIN$() function), B$FHEX (what you want)
  1771.      and B$FOCT (for the OCT$() function). This 'hexoct' module is only 50H
  1772.      bytes but you get the idea. Why clutter up your program with code for
  1773.      octal when you're doing hex?
  1774.      
  1775.         Reducing the EXE size turned out to be non-trivial. It took 3 tries
  1776.      before I was able to make any appreciable cut. I should also mention
  1777.      that I considered 4 options in addition to vanilla QB:
  1778.      
  1779.         1. Go to BASIC7 which is said to generate smaller/faster code
  1780.         2. Go to something like Crescent's PDQ which uses an alternate
  1781.            link library to generate smaller EXEs
  1782.         3. Wait for QB 5.0 or QBX or ??? from Microsoft
  1783.         4. Rewrite pEDIT in 'C'
  1784.      
  1785.         Briefly, Options 1 and 2 required major changes to the source code
  1786.      and/or a significant cash outlay. I had a major pEDIT upgrade planned
  1787.      for January 1991 and couldn't wait for Option 3. Lastly, I hate 'C' -
  1788.      so much for Option 4.
  1789.      
  1790.         After much experimentation I found one thing that can result in a
  1791.      sizeable reduction in program size plus a collection of other tricks
  1792.      that, when taken together, can reduce the size even more. The methods
  1793.      outlined here should apply to QuickBASIC 4.0(b) and 4.5.
  1794.      
  1795.      
  1796.                                Floating Point Emulation
  1797.      
  1798.         It turns out that floating point emulation code can increase the
  1799.      size of a program dramatically. QuickBASIC has to emulate floating
  1800.      
  1801.      The QBNews                                                     Page 28
  1802.      Volume  2, Number  1                                 February 28, 1991
  1803.  
  1804.      point operations in software for systems that can't do it in hardware,
  1805.      i.e.  don't have a math coprocessor.
  1806.      
  1807.         There isn't much we can do about the granularity problem as we have
  1808.      no control over what Microsoft puts in their link libraries or how
  1809.      many different procedures there are in each module. We can, however,
  1810.      do something about eliminating unnecessary floating point code. This
  1811.      turned out to be easier said than done.
  1812.      
  1813.         To see if your program contains this floating point code, generate
  1814.      a link map and look for EMULATOR_TEXT and EMULATOR_CODE. Under QB 4.5,
  1815.      these modules have lengths of 2430H and 0170H bytes, respectively. If
  1816.      this floating point support is present and you don't need it, you're
  1817.      adding an incredible 9632 bytes of code to your program.
  1818.      
  1819.         Following is a list of BASIC functions/keywords with information on
  1820.      each's use of floating point. There are some general rules to follow
  1821.      also: (1) you can't have any real variables declared - VAR! or VAR#;
  1822.      (2) don't use the real division operator / (forward slash); replace it
  1823.      by \ (back slash) which signifies integer division; (3) lastly, you
  1824.      can't use any function which is explicitly for real numbers - for
  1825.      example INT(), FIX().
  1826.      
  1827.         TIMER               Returns seconds elapsed since midnight (~18.2
  1828.                             ticks per second); replace by a FUNCTION that
  1829.                             reads the system clock and returns ticks; see
  1830.                             the sample function ReadTimer&()
  1831.      
  1832.         INPUT               Can input reals so must replace by a BASIC
  1833.                             SUB or FUNCTION that uses INKEY$ or INPUT$();
  1834.                             see the sample subprogram GetInput()
  1835.      
  1836.         INPUT #             Same as above; also see LINE INPUT #
  1837.      
  1838.         VAL()               One of the biggest offenders, ALWAYS uses fp
  1839.                             emulation, is also quite large and slow; use
  1840.                             a replacement such as the sample FUNCTION
  1841.                             StrToInt&()
  1842.      
  1843.         ABS()               Uses emulation only if the argument is a real
  1844.      
  1845.         STR$()              Uses fp emulation only if the argument is a
  1846.                             real; CAREFUL: there may be cases when the
  1847.                             compiler can't tell what the argument may be?
  1848.      
  1849.         PRINT USING         Uses emulation only if the print mask is for
  1850.                             a real number, e.g. "###.##"
  1851.      
  1852.         READ                Expected because you can READ into a real
  1853.                             variable; however you might think QB would be
  1854.                             smart enough to scan the DATA and see if any
  1855.                             is float? Replace by a DATA$ string and a
  1856.                             FUNCTION to parse it; see the sample function
  1857.                             ReadData$()
  1858.      
  1859.      The QBNews                                                     Page 29
  1860.      Volume  2, Number  1                                 February 28, 1991
  1861.  
  1862.      
  1863.         LINE INPUT #        Makes no sense at all as can *ONLY* input a
  1864.                             string! Must replace by some other method of
  1865.                             INPUTing a single line at a time; note also
  1866.                             that INPUT # and LINE INPUT # are VERY slow
  1867.                             in reading sequential ASCII text; see the
  1868.                             sample SUB InputLine()
  1869.      
  1870.         The archive contains two sample programs: SMALLEXE and LARGEEXE.
  1871.      SMALLEXE.BAS uses the mentioned InputLine(), ReadData$(), ReadTimer&
  1872.      and StrToInt&() replacements for LINE INPUT #, DATA/READ, TIMER and
  1873.      VAL(), respectively. SMALLEXE also uses the function FileExist() to
  1874.      check for the existence of a file, while LARGEEXE has to use BASIC
  1875.      error trapping. When compiled under QB 4.5 (LARGEEXE requires the /X
  1876.      option) and linked, the EXE sizes are 24102 and 36784 bytes.
  1877.      
  1878.         SMALLEXE provides another distinct advantage over LARGEEXE: file
  1879.      I/O speed. When the two programs are timed to read the same file
  1880.      without displaying the lines, SMALLEXE is 3-5 times faster! This is
  1881.      with a 4k buffer; a larger buffer should speed it up even more.
  1882.      
  1883.         The archive file SMALLFUN.TXT contains an overview of each of the
  1884.      referenced Functions and Subprograms and includes a description, an
  1885.      example of its usage, what BASIC code it replaces and a discussion of
  1886.      the input/output parameters. These routines are, with the exception of
  1887.      InputLine(), quite straightforward. InputLine() works by inputting a
  1888.      bufferfull of text from the disk and splitting it into lines based on
  1889.      the location of a carriage return/line feed pair. It is left to the
  1890.      reader to dissect InputLine() further; pay particular attention to
  1891.      what happens when a line crosses a buffer boundary.
  1892.      
  1893.      
  1894.                                  Other Tips and Tricks
  1895.      
  1896.         One easy way to reduce the EXE size - which I just rediscovered -
  1897.      is to link with NOCOM.OBJ. This object file is provided by Microsoft
  1898.      but was apparently not shipped with QB 4.5. You can use the one
  1899.      included with previous versions of QB plus I am including it in the
  1900.      SMALLEXE archive. Microsoft claims a reduction in EXE size of 4k
  1901.      bytes; I saw about 3k. Note: NOCOM can be used only if your program
  1902.      does no serial communications.
  1903.      
  1904.         Link with SMALLERR.OBJ, also from Microsoft. This saves a few bytes
  1905.      by eliminating the text of error messages; only the error number is
  1906.      displayed. You might want to do this after your program is debugged.
  1907.      
  1908.         Minimize string usage. All assigned strings (as in VAR$ = "Hello")
  1909.      have to be stored somewhere. QB limits conventional string space to a
  1910.      total of 64k so it is easy to run out... the infamous "Out of string
  1911.      space" error encountered mainly in the QB environment. If possible,
  1912.      'deassign' string variables to "" when you're done with them. Also,
  1913.      compile /S to reduce the string storage space in the object file.
  1914.      
  1915.         Eliminate the INTOLD86(X) routines declared in Microsoft's QB.BI
  1916.      
  1917.      The QBNews                                                     Page 30
  1918.      Volume  2, Number  1                                 February 28, 1991
  1919.  
  1920.      include file. These are for the old interrupt calls INT86() and
  1921.      INT86X(). The object code is in both QB.QLB and QB.LIB. It turns out
  1922.      EVERYTHING in QB.LIB is included at link time; you can again see this
  1923.      in the link map. If you don't need these old routines, build new
  1924.      QB.QLB and QB.LIB files with support only for CALL ABSOLUTE and CALL
  1925.      INTERRUPT(X). Following is a sample BAT file to do this with QB 4.5:
  1926.      
  1927.           rem
  1928.           rem Extract existing modules from QB LIBrary
  1929.           rem
  1930.           lib qb.lib *absolute *intrpt ;
  1931.           rem
  1932.           rem Build the new QuickLibrary w/o int86old
  1933.           rem
  1934.           link /quick absolute+intrpt,qb.qlb,,bqlb45 ;
  1935.           rem
  1936.           rem Build new LIBrary
  1937.           rem
  1938.           lib qb.lib absolute+intrpt ;
  1939.           rem
  1940.           del absolute.obj
  1941.           del intrpt.obj
  1942.      
  1943.         Finally, here are 3 link options that can be used to further reduce
  1944.      the EXE size:
  1945.      
  1946.          /EXEPACK    This is, as far as I know, safe to use. Microsoft
  1947.                      uses it when you compile to disk from within the
  1948.                      environment. Some kind of compression is performed
  1949.                      to save some bytes.
  1950.      
  1951.          /PACKCODE   This is another kind of packing that is not very well
  1952.                      explained in the documentation.
  1953.      
  1954.          /FAR        I have been able to use this successfully even in
  1955.                      large programs. A discussion of what it does is
  1956.                      beyond the scope of this article; truthfully, I'm not
  1957.                      sure I could explain what it does!
  1958.      
  1959.         The archive contains QBCOMP.BAT, a batch file which uses all of the
  1960.      compile and link options discussed above. Try compiling/linking a
  1961.      program as you normally would and note the size of the EXE in bytes.
  1962.      Then, use QBCOMP and see how much smaller the executable gets. I did
  1963.      this for one of the programs I wrote in the course of writing this
  1964.      article. The executable went from 28342 to 22646 bytes - a reduction
  1965.      of almost 5700 bytes without much effort!
  1966.      
  1967.      
  1968.                                     Conclusions
  1969.      
  1970.         It is possible to reduce the size of a QuickBASIC Version 4 stand-
  1971.      alone executable by some 10-12k bytes by eliminating unnecessary
  1972.      floating point emulation code and using a few compiler and linker
  1973.      options. This is not to imply that you can create executables as
  1974.      
  1975.      The QBNews                                                     Page 31
  1976.      Volume  2, Number  1                                 February 28, 1991
  1977.  
  1978.      small as possible with other languages. In the author's opinion, the
  1979.      ease of programming in a modern BASIC such as QuickBASIC far out-
  1980.      weighs the program size when compared to a user-hostile language like
  1981.      'C'. Please, no hate mail from C lovers!
  1982.      
  1983.         By eliminating floating point emulation code and applying the other
  1984.      tricks detailed above I was able to reduce the size of my editor
  1985.      (PEDIT.EXE) by 11,200 bytes. While this is not a huge reduction every
  1986.      bit helps. It would be difficult to trim this much by tweaking!
  1987.      
  1988.         Program size is not always a consideration. Sometimes you won't
  1989.      care if a program takes up 38k or 22k (or 4k). Sometimes, however, it
  1990.      is important. One example I can think of is an installation program on
  1991.      a software distribution disk. There may not be room for a 'standard'
  1992.      QuickBASIC program of 45k or so!
  1993.      
  1994.         The reader is encouraged to start with the sample functions and
  1995.      subprograms included here and build a library of routines that can,
  1996.      when size and speed are important, be used in place of their QB
  1997.      counter-parts. Feel free to modify the code to fit your needs.
  1998.      
  1999.      
  2000.      *********************************************************************
  2001.      T. G. (Terry) Muench has been in computers for 14 years and has been
  2002.      a programmer (COBOL and BASIC), systems analyst and VAX Systems
  2003.      Manager. He has been involved with micros since CP/M days and is now
  2004.      trying his hand at shareware. He is the author of pEDIT, the personal
  2005.      EDITor, and can be reached on CompuServe at [71171,2424].
  2006.      *********************************************************************
  2007.      
  2008.      [EDITORS NOTE] 
  2009.      All files for this article are contained in the file SMALLEXE.ZIP.
  2010.      
  2011.  
  2012.  
  2013.  
  2014.  
  2015.  
  2016.  
  2017.  
  2018.  
  2019.  
  2020.  
  2021.  
  2022.  
  2023.  
  2024.  
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.      The QBNews                                                     Page 32
  2033.      Volume  2, Number  1                                 February 28, 1991
  2034.  
  2035.  
  2036.  
  2037.      ----------------------------------------------------------------------
  2038.                        N e w   a n d   N o t e w o r t h y
  2039.      ----------------------------------------------------------------------
  2040.  
  2041.      
  2042.      PDQComm 2.5 from Crescent Software
  2043.      
  2044.         Crescent Software announces a major update to PDQComm, the
  2045.      communications library for QuickBASIC 4.x, BASIC 7.x PDS, and P.D.Q.
  2046.      This upgrade adds many new features while maintaining compatibility
  2047.      with previous versions. They are:
  2048.      
  2049.         * Support for two com ports open at the same time
  2050.         * Support for the NS16550 high speed UART in FIFO mode
  2051.         * XModem and ASCII file transfer protocols
  2052.         * Various windowed terminal emulations including:
  2053.               TTY
  2054.               ANSI
  2055.               VT52
  2056.               VT100
  2057.               D215
  2058.         * Support for ports with non-standard addresses or interrupts
  2059.      
  2060.         The price for PDQComm has been increased to $99 and includes a new
  2061.      manual with much more information on programming communications. Call
  2062.      Crescent at 1-800-35-BASIC or 203-438-5300 to order or inquire about
  2063.      upgrading from a previous version. You can also download a demo from
  2064.      The Crescent Software Support BBS at 203-426-5958.   
  2065.      
  2066.  
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.  
  2073.  
  2074.  
  2075.  
  2076.  
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.  
  2083.  
  2084.  
  2085.  
  2086.  
  2087.  
  2088.  
  2089.  
  2090.  
  2091.      The QBNews                                                     Page 33
  2092.      Volume  2, Number  1                                 February 28, 1991
  2093.  
  2094.  
  2095.  
  2096.      ----------------------------------------------------------------------
  2097.                    S o m e   A s s e m b l y   R e q u i r e d
  2098.      ----------------------------------------------------------------------
  2099.  
  2100.      Setting Error Levels with QuickBASIC by Dave Cleary
  2101.      
  2102.         One of the big misconceptions people have is that it is all right
  2103.      to terminate a QuickBASIC program by using CALL INTERRUPT. This is
  2104.      done by calling interrupt 21h function 4Ch. By doing this, you yank
  2105.      the machine away from QuickBASIC. This causes the numerous interrupt
  2106.      vectors QB hooks to point into nothingness. This means that somewhere,
  2107.      sometime, somehow when you least expect it, your machine will crash.
  2108.      
  2109.         Now it is very possible that you can throw together a little test
  2110.      program using INT 21h Function 4Ch and not lock up your machine. Does
  2111.      this mean I don't know what I'm talking about? No. You just hadn't
  2112.      happen to come across the right combination to cause problems. You may
  2113.      find a program you have been using for years uses this procedure
  2114.      without any problems at all. Consider yourself lucky. But as Murphy's
  2115.      Law states, as soon as you give the program to someone, their machine
  2116.      will lock up.
  2117.      
  2118.         Does this mean you cannot set error levels with QuickBASIC? No it
  2119.      doesn't. It does require you to do a little work though. When you run
  2120.      a QuickBASIC program, the QB runtime takes control over most of your
  2121.      machine. This is how BASIC offers many more built in features than
  2122.      other languages and why it is a pretty stable platform for the
  2123.      beginner. In the next few paragraphs, we will discuss how to exit QB
  2124.      with an error level by looking at a small assembler routine I put
  2125.      together.
  2126.      
  2127.         The following is the routine:
  2128.      
  2129.      ;ELEAVE.ASM - Routine to return an error level from a QuickBASIC
  2130.      ;program ; ;By David Cleary 
  2131.      
  2132.      .Model Medium, Basic 
  2133.      
  2134.      .Code 
  2135.      
  2136.         Extrn       B$CEND:Proc             ;QB termination proceedure 
  2137.      
  2138.         Level       DW 0 
  2139.         OldIntOfs   DW 0 
  2140.         OldIntSeg   DW 0 
  2141.      
  2142.      ELeave Proc , ELevel:Ptr Word
  2143.      
  2144.         Mov   BX, ELevel                    ;Get the level passed in 
  2145.         Mov   AX, [BX] 
  2146.         Mov   CS:Level, AX                  ;Save it in Level 
  2147.      
  2148.         Mov   AX, 3521h                     ;Call DOS to get its int vector 
  2149.         Int   21h 
  2150.      
  2151.      The QBNews                                                     Page 34
  2152.      Volume  2, Number  1                                 February 28, 1991
  2153.  
  2154.         Mov   CS:OldIntOfs, BX              ;ES:BX points to old vector 
  2155.         Mov   CS:OldIntSeg, ES 
  2156.      
  2157.         Mov   AX, 2521h                     ;Now set our new int vector 
  2158.         Mov   DX, Offset IntTrap 
  2159.         Push  DS 
  2160.         Push  CS 
  2161.         Pop   DS                            ;Save DS and move CS into it 
  2162.         Int   21h 
  2163.         Pop   DS                            ;Restore DS 
  2164.         Call  B$CEND                        ;Call BASIC to end 
  2165.      
  2166.      IntTrap: 
  2167.         Cmp   AH, 4Ch                       ;Wait for function 4C 
  2168.         Jne   ChainOld                    ;If not, chain to original vector 
  2169.      
  2170.         Sti                               ;It is 4C, so turn interrupts on 
  2171.         Mov   AX, 2521h                     ;Restore original vector 
  2172.         Mov   DX, CS:OldIntOfs 
  2173.         Mov   DS, CS:OldIntSeg 
  2174.         Call  CS:DWord Ptr OldIntOfs   ;We need to call it instead of chain 
  2175.      
  2176.      
  2177.         Mov   AX, CS:Level 
  2178.         Mov   AH, 4Ch                       ;Call INT 21h function 4Ch with 
  2179.                                             ;our level 
  2180.         Int   21h 
  2181.      
  2182.      ChainOld: 
  2183.         Jmp   CS:DWord Ptr OldIntOfs     ;This is our chain to the original 
  2184.      
  2185.      Leave Endp 
  2186.      
  2187.      End
  2188.      
  2189.         What you need to do to set an error level from QB is to create an
  2190.      Interrupt Service Routine (ISR). This routine will trap all calls to
  2191.      interrupt 21h. When a function 4Ch comes along, you know it is time to
  2192.      set the level.
  2193.      
  2194.         You will notice in the beginning of the program, I allocate some
  2195.      data space in the code segment. Normally, this would be allocated in
  2196.      the data segment. I can't do this here, because when our ISR is
  2197.      executed, DS will not always point to our data segment. Therefore, I
  2198.      allocate our data in the code segment and use CS overrides.
  2199.      
  2200.         I also declare an external routine called B$CEND. This is the
  2201.      internal routine QuickBASIC calls when your program terminates. After
  2202.      setting up our ISR, I call this routine to end the program.
  2203.      
  2204.         The first thing I do when ELeave is called is save the error level
  2205.      requested. By default, QuickBASIC passes everything by reference. This
  2206.      means that QuickBASIC passes an address of our variable instead of the
  2207.      value. I take the address and find the value of the variable and save
  2208.      
  2209.      The QBNews                                                     Page 35
  2210.      Volume  2, Number  1                                 February 28, 1991
  2211.  
  2212.      it for later.
  2213.      
  2214.         The next step is setting up our ISR. I do this by first getting the
  2215.      address of the old ISR. This is very important because I need it to
  2216.      chain to later on and I also need to restore it when the program
  2217.      terminates. Interrupt 21h Function 35h is the DOS routine to get
  2218.      interrupt vectors. I load AH with 35h and AL with 21h since I want the
  2219.      address of the DOS interrupt vector. The vector gets returned in ES:BX
  2220.      and is stored for later use.
  2221.      
  2222.         I now need to insert my ISR into the interrupt chain. This is done
  2223.      by using DOS Interrupt 21h Function 25h. I put my ISR address into
  2224.      DS:DX and do the interrupt. Now, all INT 21h will come to me first. I
  2225.      now am ready to terminate the program so I call B$CEND.
  2226.      
  2227.         B$CEND will start "cleaning up" your machine by restoring it to the
  2228.      state it was in before you ran your QB program. It will issue numerous
  2229.      INT 21h and when it does, IntTrap gets control first. I look into AH
  2230.      first to see what DOS function is requested. I am only interested in
  2231.      function 4Ch so if it is anything else, I chain to the old ISR. This
  2232.      is done by a simple jump. When the old ISR gets executed, it will
  2233.      never know I had control of the machine before it.
  2234.      
  2235.         Eventually B$CEND will call function 4Ch to terminate the program.
  2236.      When it does, I am ready. The first thing I have to do is uninstall
  2237.      myself from the interrupt chain. I do this by setting up an INT 21h
  2238.      Function 25h call. Instead of executing it by an INT instruction, I
  2239.      need to call it instead. This is because I am still in the interrupt
  2240.      chain and I would actually call myself. Upon return, the INT 21h
  2241.      vector is restored back to normal. All that leaves is a normal INT 21h
  2242.      Function 4Ch to set our level and terminate the program.
  2243.      
  2244.         One caveat you should be aware of. You shouldn't use this program
  2245.      in the environment. When you are in the environment, your program is
  2246.      not actually running so it never terminates. If you tried using CALL
  2247.      INTERRUPT 21h Function 4Ch in the environment, you'd find yourself at
  2248.      a DOS prompt with a pretty messed up machine.
  2249.      
  2250.      ********************************************************************** 
  2251.           Dave  Cleary is an electronics engineer for Vectron  Laboratories
  2252.      in  Norwalk, CT. Besides putting together the QBNews, he is  also  the
  2253.      author  of Crescent Software's PDQComm. He can be reached in  care  of
  2254.      this newsletter.
  2255.      **********************************************************************
  2256.      
  2257.      [EDITORS NOTE]
  2258.      All code for this article is found in ELEAVE.ZIP
  2259.      
  2260.  
  2261.  
  2262.  
  2263.  
  2264.  
  2265.  
  2266.      The QBNews                                                     Page 36
  2267.      Volume  2, Number  1                                 February 28, 1991
  2268.  
  2269.  
  2270.  
  2271.      ----------------------------------------------------------------------
  2272.           P s s t   . . .   L o o k i n g   F o r   A   L i b r a r y ?
  2273.      ----------------------------------------------------------------------
  2274.  
  2275.      An Introduction to QuickSHARE by Michael Welch
  2276.      
  2277.           Here's the  scenario:   For weeks  you have been  diligently
  2278.      coding  a major  database  application.   Your  client wants  the
  2279.      software  yesterday, but  all  of  that coding  takes  time!   In
  2280.      desperation, you turn to  your local BBS in search of  a few text
  2281.      files and  a library which  would speed the  development process.
  2282.      After browsing through the dreaded "GENERAL BASIC STUFF" section,
  2283.      you download only a handful of files that might offer assistance.
  2284.      Then, as  they unpack,  you discover  that two of  the files  are
  2285.      exactly the same.
  2286.      
  2287.           Not all  systems get  THIS cluttered, but  if you  have ever
  2288.      experienced such  a situation,  perhaps  I can  help.   I am  the
  2289.      librarian   for   QuickSHARE:     A   QuickBASIC   source   code,
  2290.      informational  text,  and  library  distribution  service.    The
  2291.      QuickSHARE  library is  divided  into  eleven different  sections
  2292.      relating   to  communications,   databases,  general   libraries,
  2293.      graphics,  source   code,  utilities,   demonstrations,  magazine
  2294.      articles,  Professional Development  System (BASIC  v.7) specific
  2295.      libraries, and Crescent's P.D.Q. specific libraries.  The service
  2296.      is available through The Shipyard BBS in Garland, Texas (a suburb
  2297.      of  Dallas),  through  support BBSs  referred  to  as "QuickSHARE
  2298.      Points,"  and through  United States and  Canadian Mail.   What's
  2299.      more, the service is completely non-profit!
  2300.      
  2301.           Each  file in the QuickSHARE library relates specifically to
  2302.      QuickBASIC, with very little emphasis on GWBASIC/BASICA.  Most of
  2303.      the general programming libraries are written in assembler, which
  2304.      can  offer you  the speed  and  power of  any other  professional
  2305.      language.  Finally, each file in the library is described in  the
  2306.      QuickSHARE Catalog, which lists the  author of the file, the size
  2307.      and date the item  was created, and a thorough description of the
  2308.      features.  To complete our scenario,  below is a segment from the
  2309.      database area of the QS Catalog:
  2310.      
  2311.      DATABASE:      A small QuickBASIC-only database
  2312.      Date:  5/89    Author: Jose Garcia     Cost:  FW       Size: 13K
  2313.      Description:   This is a small name/address database source code
  2314.                     file  that shows  how QuickBASIC  can  be used  to
  2315.                     create structured databases.  A nice job.
  2316.      
  2317.      DB:            Read dBASE files with this QuickBASIC source file
  2318.      Date:  1/88    Author:  David Perry   Cost:  FW     Size:  4K
  2319.      Description:   By the definition of the author, this native QB
  2320.                     file will allow you to "open and read dBASE III
  2321.                     .DBF and .DBT files, display their structure,
  2322.                     read data to include up to the first 4000 bytes
  2323.                     of a memo field."  Uses the structured TYPE block
  2324.                     for file i/o.  Completely modular and structured.
  2325.      
  2326.      The QBNews                                                     Page 37
  2327.      Volume  2, Number  1                                 February 28, 1991
  2328.  
  2329.                     
  2330.      QBTREE42:      B-Tree access method for QuickBASIC Programmers
  2331.      Date:  9/90    Author:  Cornel Huth     Cost:  $45    Size:  61K
  2332.      Description:   Written in a  mix of QuickBASIC and Microsoft ASM,
  2333.                     the author describes this package as a "keyed-file
  2334.                     system  based on the  b-tree sorting method."   It
  2335.                     maintains up  to 10  key fields  and also  10 data
  2336.                     files  (at  once).    This   package  contains  32
  2337.                     routines to make your  database programming easier
  2338.                     in QuickBASIC.  Running a  demo on my PC/XT with a
  2339.                     rather slow hard card resulted in 3.849 seconds to
  2340.                     produce and  delete 100 records  with the PutKey()
  2341.                     routine.   The  $45  registration includes  source
  2342.                     code  (sent to you when you register).  Cornel may
  2343.                     also be  reached via  the Fido  QUIK_BAS echo  for
  2344.                     assistance.   This  looks  like  a  fine  indexing
  2345.                     library.
  2346.      
  2347.           While this  is only a  very small sample, the  reader should
  2348.      see  that  QuickSHARE  actually resembles  that  of  a "Shareware
  2349.      Distributor," with  a few exceptions:   the service is  free, the
  2350.      catalog is electronic, and in addition to the mail service, users
  2351.      can obtain  QS files from  several Bulletin Board Systems.   Also
  2352.      unlike shareware  distributors, we  copy files  on an  individual
  2353.      basis.  You do not have to order an entire disk to obtain the one
  2354.      library that you actually want.   The only cost involved  is that
  2355.      of media and postage  (for example, $1.35 gets you one 360k disk,
  2356.      $1.85 gets two 360k disks, and  $1.65 gets you a 1.2mb disk  full
  2357.      of  whatever you wish).   If you  prefer, too, you  can even mail
  2358.      your own disks to me or to QuickSHARE Canada with  enough postage
  2359.      to cover return mail, and we will fill your order.  Therefore, if
  2360.      you are not comfortable with using a BBS, you have the  option of
  2361.      direct mail.  For a current copy of the QuickSHARE catalog, which
  2362.      lists  well  over 300  *quality*  QuickBASIC-related  files, send
  2363.      $1.35-$2.00  ($2.00 would cover  ANY media  type) to  the address
  2364.      listed at the  end of this article.   Note that QuickSHARE Canada
  2365.      at this time only supports 360k diskettes.
  2366.      
  2367.           If you are  familiar with  Bulletin Boards,  you can  obtain
  2368.      your QS  file(s) from any  of eight QuickSHARE  Points (including
  2369.      The  Shipyard).  To logon immediately without having to register,
  2370.      use Quick  Basic (two  words) for YOUR  NAME, and  use QuickSHARE
  2371.      (one word) for  YOUR PASSWORD.  Some systems will allow a maximum
  2372.      of 15 minutes access under  this special method while others will
  2373.      allow an hour.  QuickSHARE Points are listed below:
  2374.      
  2375.           The Wizards of Orchid BBS          Gulf Coast BBS
  2376.           Sysop is Jeff and Lynda Howard     Sysop is Jim Brewer
  2377.           Ferndale, MI                       New Port Richey, FL
  2378.           (313)-547-2985                     (813)-856-7926
  2379.      
  2380.           Oregon Trail Crossroads BBS        The Nest Egg BBS
  2381.           Sysop is Thomas Lange              Sysop is Tom Frye
  2382.           Casper, WY                         Lenexa, KS
  2383.      
  2384.      The QBNews                                                     Page 38
  2385.      Volume  2, Number  1                                 February 28, 1991
  2386.  
  2387.           (307)-472-3615                     (913)-492-2739
  2388.      
  2389.           The COM Port BBS                   dix MOJO BBS
  2390.           Sysop is Craig McCracken           Sysop is Dick Dennison
  2391.           Montgomery, AL                     New Hampton, NY
  2392.           (205)-260-9904                     (914)-374-3903
  2393.      
  2394.      
  2395.                 For Mail Orders and Additional BBS Services:
  2396.      
  2397.           QuickSHARE Canada                  QuickSHARE Headquarters
  2398.           Duram Systems (ONLINE) BBS         The Shipyard BBS
  2399.           Sysop is Paul Chantler             Jim Woolly/Mike Welch
  2400.           (416)-430-3812                     (214)-686-1962
  2401.           28 Lumsden Cres                    P.O. Box 801011
  2402.           Whitby Ontario, L1R 167 CANADA     Dallas, TX  75240
  2403.      
  2404.           Using libraries written by  other programmers can be a  real
  2405.      life saver.  If you have a project that  needs extra flair, or if
  2406.      you are writing an application that needs to minimize the time in
  2407.      which it takes to complete a  task, a library written in assembly
  2408.      language is the  only answer.  However, libraries  are not always
  2409.      the best route  to take.  When  portability is a factor,  or when
  2410.      one  starts  to learn  to  program,  I suggest  "reinventing  the
  2411.      wheel."  Whatever your particular situation, QuickSHARE offers an
  2412.      inexpensive  alternative  to  obtaining   quality  shareware  and
  2413.      freeware programming tools.
  2414.      
  2415.  
  2416.  
  2417.  
  2418.  
  2419.  
  2420.  
  2421.  
  2422.  
  2423.  
  2424.  
  2425.  
  2426.  
  2427.  
  2428.  
  2429.  
  2430.  
  2431.  
  2432.  
  2433.  
  2434.  
  2435.  
  2436.  
  2437.  
  2438.  
  2439.  
  2440.  
  2441.      The QBNews                                                     Page 39
  2442.  
  2443.  
  2444.      ----------------------------------------------------------------------
  2445.                                       E O F
  2446.      ----------------------------------------------------------------------
  2447.  
  2448.      Receiving The QBNews
  2449.      
  2450.           The  QBNews is distributed mainly through BBS systems around  the
  2451.      world.  Some  of  the networks it gets  distributed  through  are  SDS
  2452.      (Software   Distribution   System),  PDN   (Programmers   Distribution
  2453.      Network),  and SDN (Shareware Distribution Network). Ask the  sysop of
  2454.      your  local  board about these networks to see if there is a  node  in
  2455.      your area.
  2456.      
  2457.           The  QBNews  can  also  be found  on  CompuServe  in  the  MSLang
  2458.      (Microsoft  Language)  forum. It can be found in file area 1 or  2  of
  2459.      that  forum. Just search for the keyword QBNEWS. The QBNews will  also
  2460.      be available on PC-Link. I send them to Steve Craver, who is the BASIC
  2461.      Programming  Forum Host on PC-LINK and he will make them available.  I
  2462.      would appreciate anybody who could upload The QBNews to other services
  2463.      such as GENIE since I don't have access to these.
  2464.      
  2465.           I  have also set up a high speed distribution network for  people
  2466.      who  would  like to download The QBNews at 9600  baud.  The  following
  2467.      boards allow first time callers download privileges also. They are:
  2468.      
  2469.          Name           Sysop       Location       Number         Node #
  2470.      ---------------------------------------------------------------------
  2471.      
  2472.      Treasure Island  Don Dawson    Danbury, CT    203-791-8532   1:141/730
  2473.      
  2474.      Gulf Coast BBS   Jim Brewer New PortRichey,FL 813-856-7926   1:3619/20
  2475.      
  2476.      221B Baker St.   James Young   Panama City,FL 904-871-6536   1:3608/1
  2477.      
  2478.      EMC/80           Jim Harre     St. Louis, MO  314-843-0001   1:100/555
  2479.      
  2480.      
  2481.           Finally, you can download The QBNews from these vendors BBS's:
  2482.      
  2483.      The Crescent Software Support BBS   203-426-5958
  2484.      
  2485.      The Microhelp BUG BBS               404-552-0567
  2486.                                          404-594-9625
  2487.      
  2488.      
  2489.      You do not have to be a customer of these vendors in order to download
  2490.      The  QBNews, but the Microhelp BBS only allows non-members 15  minutes
  2491.      of time per call.
  2492.      
  2493.           If  you  would  like  to receive The QBNews on  disk,  I  am  now
  2494.      offering a subscription for volume 2 next year. If you subscribe,  you
  2495.      will  receive a disk with all the issue from volume 1, plus  you  will
  2496.      receive  4  disks next year as each of the 4 issues of volume  2  come
  2497.      out. I have decided against offering individual disks as I don't  have
  2498.      
  2499.      The QBNews                                                     Page 40
  2500.      Volume  2, Number  1                                 February 28, 1991
  2501.  
  2502.      the time to administer that. The cost of a subscription is as follows:
  2503.      
  2504.      Base Price for Volume 2:                $15.00
  2505.      Additional charge for 3.5" disks:        $5.00
  2506.      Additional charge for international:     $5.00
  2507.      
  2508.           The  base price includes 5.25" 360k disks. Send a check or  money
  2509.      order in U.S. funds to:
  2510.      
  2511.           The QBNews
  2512.           P.O. Box 507
  2513.           Sandy Hook, CT 06482
  2514.      
  2515.           Please  be  sure  to specify what archive format  you  want.  The
  2516.      QBNews normally uses PKZip as it's archiver.
  2517.      ----------------------------------------------------------------------
  2518.  
  2519.      Submitting Articles to The QBNews
  2520.      
  2521.           The QBNews relies on it's readers to submit articles. If you  are
  2522.      interested in submitting an article, please send a disk of Ascii  text
  2523.      of no more than 70 characters per line to:
  2524.      
  2525.           The QBNews
  2526.           P.O. Box 507
  2527.           Sandy Hook, CT 06482
  2528.      
  2529.      Articles can also be submitted via E-Mail. Send them via Compuserve to
  2530.      76510,1725 or via FidoNet to 1:141/777. I can be reached at the  above
  2531.      addresses as well as on Prodigy as HSRW18A.
  2532.      ----------------------------------------------------------------------
  2533.  
  2534.      
  2535.  
  2536.  
  2537.  
  2538.  
  2539.  
  2540.  
  2541.  
  2542.  
  2543.  
  2544.  
  2545.  
  2546.  
  2547.  
  2548.  
  2549.  
  2550.  
  2551.  
  2552.  
  2553.  
  2554.  
  2555.  
  2556.  
  2557.  
  2558.  
  2559.  
  2560.      The QBNews                                                     Page 41
  2561.       The QBNews Master Index for Volume 1                February 28, 1990
  2562.               Article Name                                      Vol   Issue
  2563.      ======================================================================
  2564.  
  2565.  
  2566.      Algorithms
  2567.         Fast String Searching in QuickBASIC....................  1     2
  2568.         Improving Your IQUEUE..................................  1     4
  2569.         Reversing INSTR........................................  1     2
  2570.  
  2571.      Ask Mr. Wizard
  2572.         Mr. Wizard Tells What "Bytes Free" Means...............  1     2
  2573.  
  2574.      BASIC 7.X PDS
  2575.         Microsoft Professional BASIC 7.0 Product Announcement..  1     2
  2576.  
  2577.      Beginners Corner
  2578.         Basic Menuing and Graphics.............................  1     3
  2579.         Common Questions about QuickBASIC......................  1     5
  2580.         How to Use Libraries in QuickBASIC.....................  1     5
  2581.         The BASICS of QB's Serial Communications...............  1     4
  2582.  
  2583.      CALL INTERRUPT
  2584.         Directory Swapping.....................................  1     3
  2585.         Format Floppy Disks with QB............................  1     5
  2586.         Getting the Day of the Week with CALL INTERRUPT........  1     3
  2587.         QuickBASIC Directories.................................  1     1
  2588.         Screen Scrolling with CALL INTERRUPT...................  1     3
  2589.         Self-Cloning Exe's Revisited...........................  1     5
  2590.         Using a FOSSIL - Take 1................................  1     4
  2591.         Using a FOSSIL - Take 2................................  1     4
  2592.         Using the PSP..........................................  1     2
  2593.  
  2594.      Chris Wagner
  2595.         Using a FOSSIL - Take 2................................  1     4
  2596.  
  2597.      Communications
  2598.         A Pop-Up Communications Program with P.D.Q.............  1     4
  2599.         The BASICS of QB's Serial Communications...............  1     4
  2600.         Using a FOSSIL - Take 1................................  1     4
  2601.         Using a FOSSIL - Take 2................................  1     4
  2602.  
  2603.      Cornel Huth
  2604.         Format Floppy Disks with QB............................  1     5
  2605.  
  2606.      Crescent Software
  2607.         A Pop-Up Communications Program with P.D.Q.............  1     4
  2608.         Don Malin's Cross Reference Program Announcement.......  1     4
  2609.         P.D.Q. Product Announcement............................  1     1
  2610.         Peeking at DOS with P.D.Q..............................  1     4
  2611.  
  2612.      DOS
  2613.         Directory Swapping.....................................  1     3
  2614.         Fast File I/O..........................................  1     3
  2615.       The QBNews Master Index for Volume 1              February 28, 1990
  2616.               Article Name                                      Vol   Issue
  2617.      ======================================================================
  2618.  
  2619.  
  2620.      DOS
  2621.         Format Floppy Disks with QB............................  1     5
  2622.         Getting the Day of the Week with CALL INTERRUPT........  1     3
  2623.         Peeking at DOS with P.D.Q..............................  1     4
  2624.         QuickBASIC Directories.................................  1     1
  2625.         Returning ErrorLevels to QB............................  1     2
  2626.         Using the PSP..........................................  1     2
  2627.  
  2628.      Database
  2629.         DBase III File Viewer..................................  1     5
  2630.         Index Manager Product Announcement.....................  1     2
  2631.         Index Manager Review...................................  1     3
  2632.         Index Manager for PDS-7 and Networks Announcement......  1     4
  2633.  
  2634.      Dave Cleary
  2635.         A Pop-Up Communications Program with P.D.Q.............  1     4
  2636.         GPIB Instrument Control from IOTech....................  1     5
  2637.         Memory Moves with QB...................................  1     1
  2638.  
  2639.      Directory
  2640.         Directory Swapping.....................................  1     3
  2641.         QuickBASIC Directories.................................  1     1
  2642.  
  2643.      Engineers Corner
  2644.         GPIB Instrument Control from IOTech....................  1     5
  2645.  
  2646.      Ethan Winer
  2647.         Fast File I/O..........................................  1     3
  2648.         Fast String Searching in QuickBASIC....................  1     2
  2649.         Peeking at DOS with P.D.Q..............................  1     4
  2650.  
  2651.      File IO
  2652.         Fast File I/O..........................................  1     3
  2653.         QuickBASIC Directories.................................  1     1
  2654.  
  2655.      Frederick Volking
  2656.         Getting and Putting Graphics...........................  1     2
  2657.  
  2658.      Graphics
  2659.         Basic Menuing and Graphics.............................  1     3
  2660.         GEOGRAF Level One Announcement.........................  1     4
  2661.         Getting and Putting Graphics...........................  1     2
  2662.         Getting the .PCX Palette Info..........................  1     5
  2663.         Graphics and Text Screen Dumps.........................  1     5
  2664.         Saving and Loading .PCX Files..........................  1     5
  2665.  
  2666.      Harold Thomsom
  2667.         Returning ErrorLevels to QB............................  1     2
  2668.  
  2669.      Hector Plasmic
  2670.         Directory Swapping.....................................  1     3
  2671.       The QBNews Master Index for Volume 1              February 28, 1990
  2672.               Article Name                                      Vol   Issue
  2673.      ======================================================================
  2674.  
  2675.  
  2676.      Hector Plasmic
  2677.         QuickBASIC Directories.................................  1     1
  2678.         Using a FOSSIL - Take 1................................  1     4
  2679.         Using the PSP..........................................  1     2
  2680.  
  2681.      Jim Mack
  2682.         Improving Your IQUEUE..................................  1     4
  2683.         Programming UEVENT.....................................  1     3
  2684.  
  2685.      Keyboard
  2686.         A Replacement for INPUT................................  1     3
  2687.         Basic Menuing and Graphics.............................  1     3
  2688.         Extended Key Codes.....................................  1     2
  2689.         Menus..................................................  1     2
  2690.         Yes/No Response DEF FN.................................  1     3
  2691.  
  2692.      Larry Stone
  2693.         A Pop-Up Calculator with Stay Res......................  1     4
  2694.         How to Make a Self-Cloning Exe in QuickBASIC...........  1     3
  2695.         MicroHelp's QB Optimizer - How to Save Some Bytes......  1     1
  2696.         Reversing INSTR........................................  1     2
  2697.         Scenic Views by Way of the Video Map...................  1     5
  2698.         Update on MicroHelp's QB Optimizer.....................  1     2
  2699.  
  2700.      Libraries
  2701.         A Pop-Up Calculator with Stay Res......................  1     4
  2702.         A Pop-Up Communications Program with P.D.Q.............  1     4
  2703.         GEOGRAF Level One Announcement.........................  1     4
  2704.         How to Use Libraries in QuickBASIC.....................  1     5
  2705.         Index Manager Product Announcement.....................  1     2
  2706.         Index Manager Review...................................  1     3
  2707.         Index Manager for PDS-7 and Networks Announcement......  1     4
  2708.         MicroHelp's QB Optimizer - How to Save Some Bytes......  1     1
  2709.         P-Screen Announcement..................................  1     3
  2710.         P-Screen+ and P-Screen Professional Review.............  1     3
  2711.         P.D.Q. Product Announcement............................  1     1
  2712.         Peeking at DOS with P.D.Q..............................  1     4
  2713.         Update on MicroHelp's QB Optimizer.....................  1     2
  2714.  
  2715.      MicroHelp
  2716.         A Pop-Up Calculator with Stay Res......................  1     4
  2717.         MicroHelp Library Manager Product Announcement.........  1     2
  2718.         MicroHelp's QB Optimizer - How to Save Some Bytes......  1     1
  2719.         Update on MicroHelp's QB Optimizer.....................  1     2
  2720.  
  2721.      Microsoft
  2722.         Microsoft Professional BASIC 7.0 Product Announcement..  1     2
  2723.  
  2724.      Power Programming
  2725.         How to Make a Self-Cloning Exe in QuickBASIC...........  1     3
  2726.       The QBNews Master Index for Volume 1              February 28, 1990
  2727.               Article Name                                      Vol   Issue
  2728.      ======================================================================
  2729.  
  2730.  
  2731.      Power Programming
  2732.         Programming UEVENT.....................................  1     3
  2733.         Scenic Views by Way of the Video Map...................  1     5
  2734.         Self-Cloning Exe's Revisited...........................  1     5
  2735.  
  2736.      Product Announcements
  2737.         Don Malin's Cross Reference Program Announcement.......  1     4
  2738.         GEOGRAF Level One Announcement.........................  1     4
  2739.         Index Manager Product Announcement.....................  1     2
  2740.         Index Manager for PDS-7 and Networks Announcement......  1     4
  2741.         MicroHelp Library Manager Product Announcement.........  1     2
  2742.         Microsoft Professional BASIC 7.0 Product Announcement..  1     2
  2743.         P-Screen Announcement..................................  1     3
  2744.         P.D.Q. Product Announcement............................  1     1
  2745.  
  2746.      Ranjit Aiyagari
  2747.         The BASICS of QB's Serial Communications...............  1     4
  2748.  
  2749.      Ronny Ong
  2750.         Self-Cloning Exe's Revisited...........................  1     5
  2751.  
  2752.      Ryan Snodgrass
  2753.         Basic Menuing and Graphics.............................  1     3
  2754.  
  2755.      Screen
  2756.         Memory Moves with QB...................................  1     1
  2757.         P-Screen Announcement..................................  1     3
  2758.         P-Screen+ and P-Screen Professional Review.............  1     3
  2759.         Scenic Views by Way of the Video Map...................  1     5
  2760.         Screen Scrolling with CALL INTERRUPT...................  1     3
  2761.         Windowing Routines with Shading........................  1     3
  2762.  
  2763.      Some Assembly Required
  2764.         Assembler Programming for QuickBASIC...................  1     3
  2765.         Returning ErrorLevels to QB............................  1     2
  2766.  
  2767.      Strings
  2768.         Fast String Searching in QuickBASIC....................  1     2
  2769.         How to Make a Self-Cloning Exe in QuickBASIC...........  1     3
  2770.         Reversing INSTR........................................  1     2
  2771.  
  2772.      Swap Shop
  2773.         A QuickBASIC Archive File Viewer.......................  1     5
  2774.         A Replacement for INPUT................................  1     3
  2775.         DBase III File Viewer..................................  1     5
  2776.         Extended Key Codes.....................................  1     2
  2777.         Getting the .PCX Palette Info..........................  1     5
  2778.         Getting the Day of the Week with CALL INTERRUPT........  1     3
  2779.         Graphics and Text Screen Dumps.........................  1     5
  2780.       The QBNews Master Index for Volume 1              February 28, 1990
  2781.               Article Name                                      Vol   Issue
  2782.      ======================================================================
  2783.  
  2784.  
  2785.      Swap Shop
  2786.         Menus..................................................  1     2
  2787.         Saving and Loading .PCX Files..........................  1     5
  2788.         Screen Scrolling with CALL INTERRUPT...................  1     3
  2789.         Windowing Routines with Shading........................  1     3
  2790.         Yes/No Response DEF FN.................................  1     3
  2791.  
  2792.      TSR
  2793.         A Pop-Up Calculator with Stay Res......................  1     4
  2794.         A Pop-Up Communications Program with P.D.Q.............  1     4
  2795.         Peeking at DOS with P.D.Q..............................  1     4
  2796.  
  2797.      The Tool Shed
  2798.         Index Manager Review...................................  1     3
  2799.         MicroHelp's QB Optimizer - How to Save Some Bytes......  1     1
  2800.         P-Screen+ and P-Screen Professional Review.............  1     3
  2801.         Update on MicroHelp's QB Optimizer.....................  1     2
  2802.  
  2803.      Tips
  2804.         Mr. Wizard Tells What "Bytes Free" Means...............  1     2
  2805.         QB Quirks..............................................  1     1
  2806.  
  2807.      Tom Hanlin
  2808.         Assembler Programming for QuickBASIC...................  1     3
  2809.         Common Questions about QuickBASIC......................  1     5
  2810.         How to Use Libraries in QuickBASIC.....................  1     5
  2811.  
  2812.      Tools
  2813.         Don Malin's Cross Reference Program Announcement.......  1     4
  2814.         MicroHelp Library Manager Product Announcement.........  1     2
  2815.         MicroHelp's QB Optimizer - How to Save Some Bytes......  1     1
  2816.         Microsoft Professional BASIC 7.0 Product Announcement..  1     2
  2817.         Update on MicroHelp's QB Optimizer.....................  1     2
  2818.  
  2819.      Under The Hood
  2820.         Fast File I/O..........................................  1     3
  2821.         Memory Moves with QB...................................  1     1
  2822.  
  2823.      XRef
  2824.         Don Malin's Cross Reference Program Announcement.......  1     4
  2825.      
  2826.